home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime vr / vrscript / vrscript.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  145.2 KB  |  4,280 lines

  1. //////////
  2. //
  3. //    File:        VRScript.c
  4. //
  5. //    Contains:    Functions for script file processing.
  6. //
  7. //    Written by:    Tim Monroe
  8. //
  9. //    Copyright:    © 1997-1999 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //    Change History (most recent first):
  12. //
  13. //       <60>         06/24/99        rtm        major overhaul of geometry handling, using newly-revised code from
  14. //                                        VRMovies project; removied VRScript_RemoveBackBufferImagingProc
  15. //       <59>         06/23/99        rtm        added support for SIOUX (conditionalized using USE_SIOUX_FOR_DEBUG flag)
  16. //       <58>         05/27/99        rtm        moved VRScript_MakeFSSpecForPathName into new file, FileUtilities.c; now
  17. //                                        relative pathnames work on Windows too
  18. //       <57>         05/26/99        rtm        added VRScript_MakeFSSpecForPathName
  19. //       <56>         05/20/99        rtm        added SetVerboseState command (_OpenDebugWindow and _PrintToDebugWindow)
  20. //       <55>         05/17/99        rtm        tweaked VRScript_InstallBackBufferImagingProc and revisited modifications
  21. //                                        in <54>: we again support real-time rotation of back buffer movies if the
  22. //                                        back buffer is not oriented horizontally
  23. //       <54>         04/05/99        rtm        added kQTVRBackBufferHorizontal to flags in _InstallBackBufferImagingProc;
  24. //                                        from now on, we assume that our back buffer is horizontal and we no longer
  25. //                                        support real-time rotation of back buffer movies
  26. //       <53>         03/04/99        rtm        added VRScript_MoviePrePrerollCompleteProc, based on code from Tom Dowdy
  27. //       <52>         01/04/99        rtm        changed AtClickHS command into AtClickHSID and AtClickHSType commands
  28. //       <51>         12/17/98        rtm        removed VRScript_SetHotSpotState (moved code into _ProcessScriptCommandLine);
  29. //                                        added VRScript_SetCurrentDirectory and SetCurrentDirectory command
  30. //       <50>         12/16/98        rtm        tweaked VRScript_DeleteListOfType
  31. //       <49>         12/07/98        rtm        fixed VRScript_SetCurrentMovie to work with URLs to wired movies
  32. //       <48>         12/02/98        rtm        added VRScript_SetCurrentMovie; added URLUtilities.c to project
  33. //       <47>         11/28/98        rtm        reworked parser in VRScript_ProcessScriptCommandLine to use a hash table,
  34. //                                        using routines in VRHash.c; the basic idea was inspired by Jon Summers' code
  35. //                                        in his mTropolis VRScript MOD, but my implementation is different from his 
  36. //       <46>         11/24/98        rtm        added SetTrackState, SetTrackLayer, SetMovieTime, SetMovieRate, 
  37. //                                        and SetMovieTimeScale commands
  38. //       <45>         11/19/98        rtm        added VRScript_OpenCommandLineScriptFile, to support scripts dropped
  39. //                                        onto the Windows version
  40. //       <44>         11/18/98        rtm        removed some variable initializations to work around CW compiler bugs
  41. //       <43>         09/04/98        rtm        added SetTrackVolume
  42. //       <42>         06/19/98        rtm        added support for clicking on sprites in sprite tracks, using code from
  43. //                                        QTSprites sample; added theTolerance parameter to VRScript_FloatsAreEqual
  44. //       <41>         04/09/98        rtm        added check for empty command lines in VRScript_ProcessScriptCommandLine
  45. //       <40>         04/06/98        rtm        added Destroy3DObject command, based loosely on code from Bill Meikle
  46. //       <39>         03/12/98        rtm        added AtClickCustomButton to handle user clicks on the custom controller button
  47. //       <38>         03/09/98        rtm        added VRScript_FloatsAreEqual
  48. //       <37>         02/25/98        rtm        revised VRScript_EnteringNodeProc to call MoviesTask instead of QTVRUpdate
  49. //       <36>         12/12/97        rtm        fixed VRScript_FindAndOpenQTVRMovieFile (was opening the movie file
  50. //                                        instead of allowing DoCreateMovieWindow to do so)
  51. //       <35>         10/29/97        rtm        finished adding support for QuickTime video effects
  52. //       <34>         10/27/97        rtm        began adding support for QuickTime video effects
  53. //       <33>         10/06/97        rtm        fixed bug in replace cursor commands (wouldn't restore original
  54. //                                        cursors if a click on the hot spot caused the node to be exited)
  55. //       <32>         09/10/97        rtm        made changes necessary to compile for Windows execution
  56. //       <31>         07/21/97        rtm        added VRScript_DumpUnexpiredCommands
  57. //       <30>         07/17/97        rtm        revised all list-walking code to avoid dangling pointers
  58. //       <29>         07/15/97        rtm        reworked VRScript_MouseOverHotSpotProc to use a single while loop
  59. //       <28>         07/14/97        rtm        fixed SetHotSpotTypeCursors to use OSTypes
  60. //       <27>         07/12/97        rtm        fixed a bug in VRScript_FindAndOpenQTVRMovieFile
  61. //       <26>         07/11/97        rtm        added support for encoded commands
  62. //       <25>         07/08/97        rtm        added SetHotSpotTypeCursors command
  63. //       <24>         07/07/97        rtm        added ReplaceResource and SetHotSpotIDCursors commands
  64. //       <23>         06/19/97        rtm        added PlaySceneSound and PlaySceneQTMidi, for persistent sounds
  65. //       <22>         06/13/97        rtm        added code to make sure QD3D present before executing 3D commands
  66. //       <21>         06/12/97        rtm        added VRScript_FindAndOpenQTVRMovieFile
  67. //       <20>         06/05/97        rtm        added VRScript_SetControllerButtonState;
  68. //                                        changed semantics of SetVariable and If commands
  69. //       <19>         06/04/97        rtm        added Mode parameter to SetPanTiltZoom;
  70. //       <18>         05/30/97        rtm        added script-defined variables (SetVariable and If commands)
  71. //       <17>         05/22/97        rtm        added ability to cancel node exit to VRScript_LeavingNodeProc
  72. //       <16>         05/01/97        rtm        code clean-up: put list heads into an array
  73. //       <15>         04/28/97        rtm        added support for QuickTime MIDI files
  74. //       <14>         04/17/97        rtm        added VRScript_DelistEntry; added fMaxExecutions to some commands
  75. //       <13>         04/10/97        rtm        added 3D object and 3D sound "Set" calls
  76. //       <12>         04/07/97        rtm        added SetResizeState
  77. //       <11>         04/02/97        rtm        added support for 3DMF files
  78. //       <10>         04/01/97        rtm        added VRScript_CheckForAngleCommands
  79. //       <9>         03/31/97        rtm        added node-entry and node-exit command support;
  80. //                                        added support for additional imaging and interaction properties
  81. //       <8>         03/21/97        rtm        added VRScript_SetHotSpotState
  82. //       <7>         03/17/97        rtm        localized embedded QuickTime movie sounds
  83. //       <6>         03/13/97        rtm        reworked hot spot sounds; fixed code for 680x0 compilation;
  84. //                                        added support for angle commands
  85. //       <5>         03/12/97        rtm        added support for mouse-over hot spot commands, external resource files,
  86. //                                        hot spot click commands, and QT movies;
  87. //       <4>         03/11/97        rtm        added support for timed commands (cool!)
  88. //       <3>         03/10/97        rtm        added support for controller bar, localized sounds, and overlay pictures
  89. //       <2>         03/07/97        rtm        got hot spot sounds working (except for any options)
  90. //       <1>         03/06/97        rtm        first file
  91. //
  92. //
  93. //    This file contain functions that support an external text script file for driving QuickTime VR movies.
  94. //  The script file contains one command per line; a command line is a command word followed by one or more
  95. //    command parameters. The number and meaning of the parameters depends on the command word. See the file 
  96. //    "Script Syntax" for a complete description of the scripting language.
  97. //
  98. //////////
  99.  
  100.  
  101. //////////
  102. //       
  103. // header files
  104. //       
  105. //////////
  106.  
  107. #include "ComApplication.h"
  108.  
  109. // header files for special features
  110. #include "VRSound.h"
  111. #include "VRPicture.h"
  112. #include "VRMovies.h"
  113. #include "VR3DObjects.h"
  114. #include "VR3DTexture.h"
  115. #include "VREffects.h"
  116. #include "VRHash.h"
  117.  
  118. #include "VRScript.h"
  119.  
  120.  
  121. //////////
  122. //       
  123. // global variables
  124. //       
  125. //////////
  126.  
  127. Boolean                    gReadingScriptFile;                        // are we reading a script file?
  128. Boolean                    gIsVerbose = false;                        // are we in verbose mode?
  129.  
  130. WindowPtr                gDebugWindow = NULL;                    // the verbose mode debug window
  131.  
  132. char                    gScriptFileName[kMaxFileNameLength];    // the name of the script file
  133. MovieController            gPreviousMC = NULL;                        // a controller that's been replaced by a call to ReplaceMainMovie                
  134. Movie                    gPreviousMovie = NULL;                    // a movie that's been replaced by a call to ReplaceMainMovie        
  135.  
  136. extern Boolean            gHasSoundSprockets;                        // is SoundSprockets available?
  137. extern Boolean            gHasSoundManager30;                        // is Sound Manager version 3.0 (or greater) available?
  138. extern Boolean            gHasQuickDraw3D;                        // is QuickDraw 3D available?
  139. extern Boolean            gHasQuickDraw3D15;                        // is QuickDraw 3D version 1.5 (or greater) available?
  140. extern Boolean            gHasQTVideoEffects;                        // are the QuickTime video effects available?
  141.  
  142. extern long                gAbsoluteElapsedTime;
  143. extern long                gNodeStartingTime;
  144. extern long                gNodeElapsedTime;
  145.  
  146. extern VRScriptPrefsHdl    gPreferences;                            // a handle to the global preferences record
  147.  
  148. extern Rect                gLimitRect;                                // max size for any window
  149.  
  150.  
  151. //////////
  152. //
  153. // VRScript_OpenScriptFile
  154. // Open the external script file and process the commands (one command per line).
  155. //
  156. //////////
  157.  
  158. void VRScript_OpenScriptFile (WindowObject theWindowObject, char *theFileName)
  159. {
  160.     FILE        *myFile;
  161.     char        myString[kMaxCmdLineLength];
  162.     
  163.     if (theFileName == NULL)
  164.         return;
  165.         
  166.     myFile = fopen(theFileName, "r");
  167.     if (myFile == NULL)
  168.         return;
  169.  
  170.     gReadingScriptFile = true;
  171.  
  172.     while (fgets(myString, sizeof(myString), myFile) != NULL)
  173.         VRScript_ProcessScriptCommandLine(theWindowObject, myString);
  174.  
  175.     gReadingScriptFile = false;
  176.  
  177.     fclose(myFile);
  178. }
  179.  
  180.  
  181. #if TARGET_OS_WIN32
  182. //////////
  183. //
  184. // VRScript_OpenCommandLineScriptFile
  185. // Parse the command line when the application first starts up and
  186. // open as script files any files specified on the command line.
  187. //
  188. // Based on the routine DoOpenCommandLineMovies in WinFramework.c.
  189. //
  190. //////////
  191.  
  192. void VRScript_OpenCommandLineScriptFile (LPSTR theCmdLine)
  193. {
  194. #pragma unused(theCmdLine)
  195.     LPSTR                myCmdLine;
  196.     FSSpec                myFSSpec;
  197.     WIN32_FIND_DATA        myFile;
  198.     HANDLE                myFindFile;
  199.     char                 myFilePath[MAX_PATH];
  200.     
  201.     // get the command line for the current process
  202.     myCmdLine = GetCommandLine();
  203.  
  204.     // parse the command line
  205.     if (*myCmdLine) {
  206.         LPSTR            myTempLine;
  207.         
  208.         // the string preceding any white space is the name of the module (that is, the application)
  209.         myTempLine = strchr(myCmdLine, ' ');
  210.         if (myTempLine) {
  211.             myCmdLine = myTempLine;                  // skip the name of the application
  212.             while (*myCmdLine == ' ')
  213.                 myCmdLine++;                        // skip spaces to end of string or to first command
  214.  
  215.             while (*myCmdLine != '\0') {
  216.                 char     myFileName[MAX_PATH];
  217.                 char     myTempName[MAX_PATH];
  218.                 char     myBuffName[MAX_PATH];
  219.                 int     myIndex;
  220.                 
  221.                 // read thru the remaining string to find file names
  222.                 for (myIndex = 0; *myCmdLine != '\0'; myIndex++, myCmdLine++) {
  223.                     // if we encounter a space character, it might be a filename delimiter or a space in the filename;
  224.                     // we'll try to open the filename we have so far to see whether it's a valid filename; if not, the
  225.                     // space must be part of the filename we're constructing
  226.                     if (*myCmdLine == ' ') {
  227.                         HANDLE                myFindFile;
  228.                         WIN32_FIND_DATA        myFile;
  229.                     
  230.                         myTempName[myIndex] = '\0';
  231.                         strcpy(myBuffName, myTempName);
  232.                         
  233.                         myFindFile = FindFirstFile(myBuffName, &myFile);
  234.                         if (myFindFile != INVALID_HANDLE_VALUE) {
  235.                             // we found a file having the specified name; close our file search and
  236.                             // break out of our character-gobbling loop (since we've got a valid filename)
  237.                             FindClose(myFindFile);
  238.                             break;
  239.                         }
  240.                     }
  241.                 
  242.                     // if we made it here, *myCmdLine is part of the filename (possibly a space)
  243.                     myFileName[myIndex] = myTempName[myIndex] = *myCmdLine;
  244.                 }
  245.                 
  246.                 if (*myCmdLine != '\0')
  247.                     myCmdLine++;
  248.                 
  249.                 // add a terminating NULL character
  250.                 myFileName[myIndex] = '\0';
  251.  
  252.                 // myFileName is in 8.3 form; call FindFirstFile again to convert it to a long name
  253.                 // and then make an FSSpec record using the long file name
  254.                 
  255.                 // get the directory path
  256.                 NativePathNameToFSSpec(myFileName, &myFSSpec, 0L);
  257.                 FSSpecToNativePathName(&myFSSpec, myFilePath, MAX_PATH, kDirectoryPathOnly);
  258.                 
  259.                 myFindFile = FindFirstFile(myFileName, &myFile);
  260.                 if (myFindFile != INVALID_HANDLE_VALUE) {
  261.                     strcat(myFilePath, kFilePathSepString);                    // the path separator
  262.                     strcat(myFilePath, myFile.cFileName);
  263.                     NativePathNameToFSSpec(myFilePath, &myFSSpec, 0L);
  264.                     FindClose(myFindFile);
  265.                 } else {
  266.                     // if FindFirstFile fails, just use the 8.3 name
  267.                     NativePathNameToFSSpec(myFileName, &myFSSpec, 0L);
  268.                 }
  269.  
  270.                 // open the script file; get the QTVR movie specified in it
  271.                 VRScript_FindAndOpenQTVRMovieFile(&myFSSpec);
  272.             }
  273.  
  274.         } else
  275.             myCmdLine += strlen(myCmdLine);           // point to NULL
  276.     }
  277. }
  278. #endif    // TARGET_OS_WIN32
  279.  
  280.  
  281. //////////
  282. //
  283. // VRScript_FindAndOpenQTVRMovieFile
  284. // Open the specified script file and look for the first OpenQTVRMovieFile command in it;
  285. // open the specified movie file if one is found.
  286. //
  287. //////////
  288.  
  289. void VRScript_FindAndOpenQTVRMovieFile (FSSpec *theFSSpecPtr)
  290. {
  291.     FILE        *myFile = NULL;
  292.     char        myString[kMaxCmdLineLength];
  293.     char        myCommand[kMaxCmdWordLength];
  294.     
  295.     // set the default directory and volume to be those of the script file, not the application
  296.     VRScript_SetCurrentDirectory(theFSSpecPtr);
  297.     
  298.     // convert the filename to a C string
  299.     memcpy(gScriptFileName, &theFSSpecPtr->name[1], theFSSpecPtr->name[0]);
  300.     gScriptFileName[theFSSpecPtr->name[0]] = '\0';
  301.     
  302.     // open the script file            
  303.     myFile = fopen(gScriptFileName, "r");
  304.     if (myFile == NULL)
  305.         return;
  306.  
  307.     // search through the script file for a line beginning "OpenQTVRMovieFile"
  308.     while (fgets(myString, sizeof(myString), myFile) != NULL) {
  309.     
  310.         // get the command word
  311.         sscanf(myString, "%s ", myCommand);
  312.         if (strlen(myCommand) == 0)
  313.             break;
  314.     
  315.          // open the specified VR movie file
  316.         if (strcmp(myCommand, "OpenQTVRMovieFile") == 0) {
  317.             char        myPathName[kMaxFileNameLength];
  318.             UInt32        myOptions;
  319.             FSSpec        myFSSpec;
  320.  
  321.             sscanf(myString, "%*s %ld %s", &myOptions, myPathName);
  322.             VRScript_UnpackString(myPathName);
  323.             
  324.             // create an FSSpec that picks out the QTVR movie file; if myPathName is a full pathname,
  325.             // then use the movie file (if any) that it picks out; otherwise, look for a file having
  326.             // that name in the same directory as the script file (which is now the current directory)
  327.             FileUtils_MakeFSSpecForPathName(theFSSpecPtr->vRefNum, theFSSpecPtr->parID, myPathName, &myFSSpec);
  328.  
  329.             // now act as if "Open" were chosen from the File menu....
  330.             DoCreateMovieWindow(NULL, &myFSSpec);
  331.             
  332.             // break out of the while loop
  333.             break;
  334.         }
  335.     }
  336.     
  337.     fclose(myFile);
  338. }
  339.  
  340.  
  341. //////////
  342. //
  343. // VRScript_ProcessScriptCommandLine
  344. // Process a script command line.
  345. //
  346. // Remember that this application is intended to illustrate how to integrate media with
  347. // QuickTime VR movies; it is not meant to provide a commercial-quality scripting language
  348. // and parser. You've been warned!
  349. //
  350. //////////
  351.  
  352. void VRScript_ProcessScriptCommandLine (WindowObject theWindowObject, char *theCommandLine)
  353. {
  354.     UInt32        myResID;
  355.     UInt32        myNodeID;
  356.     UInt32        myOptions;
  357.     UInt32        myUInt32;
  358.     UInt32        myEntryID;
  359.     UInt32        mySpriteID;
  360.     UInt32        myHotSpotID;
  361.     SInt32        myMaxTimes;
  362.     float        myPanAngle;
  363.     float        myTiltAngle;
  364.     float        myFOVAngle;
  365.     float        myMinAngle;
  366.     float        myMaxAngle;
  367.     float        myTempAngle;
  368.     float        myFloat;
  369.     char        myCommand[kMaxCmdWordLength];
  370.     char        myCmdLine[kMaxCmdLineLength];
  371.     char        myPathName[kMaxFileNameLength];
  372.     UInt32        myCode;                                // the command code for myCommand
  373.     
  374.     //////////
  375.     //
  376.     // do any necessary preprocessing on the command line
  377.     //
  378.     //////////
  379.     
  380.     // decode the string, if necessary;
  381.     // any line that begins with '@' is assumed to be encoded using a simple rotate-11 scheme
  382.     if (theCommandLine[0] == '@') {
  383.         theCommandLine++;                            // get rid of the '@'
  384.         VRScript_DecodeString(theCommandLine);        // decode the rest of the command
  385.     }
  386. #if ONLY_ENCODED_SCRIPTS
  387.     else {
  388.         if (gReadingScriptFile)
  389.             return;                                    // we allow only encoded scripts
  390.     }
  391. #endif
  392.  
  393.     // strip off any leading white space
  394.     while (isspace(theCommandLine[0]))
  395.         theCommandLine++;
  396.         
  397.     //////////
  398.     //
  399.     // filter out an otiose command line
  400.     //
  401.     //////////
  402.     
  403.     // ignore an empty command line
  404.     if (strlen(theCommandLine) == 0)
  405.         return;
  406.  
  407.     // any line that begins with '#' is a comment; ignore it
  408.     if (theCommandLine[0] == '#')
  409.         return;
  410.         
  411.     //////////
  412.     //
  413.     // if verbose mode is on, display the current command in our debug window
  414.     //
  415.     //////////
  416.  
  417.     if (gIsVerbose) {
  418.         // first, make sure the debug window is open
  419.         if (gDebugWindow == NULL)
  420.             gDebugWindow = VRScript_OpenDebugWindow();
  421.  
  422.         // write the current command into the debug window
  423.         VRScript_PrintToDebugWindow(theCommandLine);
  424.     }
  425.         
  426.     //////////
  427.     //
  428.     // extract the command word from the command line
  429.     //
  430.     //////////
  431.  
  432.     sscanf(theCommandLine, "%s ", myCommand);
  433.     if (strlen(myCommand) == 0)
  434.         return;
  435.         
  436.     //////////
  437.     //
  438.     // process the command word
  439.     //
  440.     //////////
  441.     
  442.     myCode = VRHash_GetCommandCode(myCommand);
  443.     switch (myCode) {
  444.         case kOpenQTVRMovieFile:
  445.             break;
  446.             
  447.         case kSetVerboseState:            // turn verbose mode on or off
  448.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  449.  
  450.             if (myUInt32 == kVRState_Toggle)
  451.                 myUInt32 = !gIsVerbose;
  452.                 
  453.             gIsVerbose = (Boolean)myUInt32;
  454.             
  455. #if !USE_SIOUX_FOR_DEBUG
  456.             if (gDebugWindow != NULL)
  457.                 ShowHide(gDebugWindow, gIsVerbose);
  458. #endif
  459.             break;
  460.         
  461.         case kReplaceMainMovie: {        // open the specified QuickTime movie in place of the current one
  462.             UInt32        myOverlayType;
  463.             UInt32        myNameType;
  464.             
  465.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myOverlayType, &myNameType, &myOptions, myPathName);
  466.             VRScript_SetCurrentMovie(theWindowObject, myOverlayType, myNameType, myOptions, myPathName);
  467.             break;
  468.         }
  469.         
  470.         case kSetCurrentDirectory: {    // set the directory to search for content files
  471.         
  472.             // NOTE: as currently implemented, the "current directory" is set for the application, not for
  473.             // each open QTVR movie; this means that one QTVR movie can change the current directory and thus
  474.             // affect the search path of another open QTVR movie. This isn't optimal. It would be possible to
  475.             // fix this and attach a current directory to each open QTVR movie; however, the main use of this
  476.             // command is likely to be inside of the script file that's read when a QTVR movie is first opened.
  477.             // So I haven't bothered to do the work necessary to prevent current directory collisions. I might
  478.             // fix this at some point in the future.
  479.             
  480.             // NOTE: The pathname that is read from the command line must specify *a file* in the directory to
  481.             // be made current. The specified file does not actually need to exist, but the directory must.
  482.  
  483.             FSSpec        myFSSpec;
  484.             
  485.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  486.             VRScript_UnpackString(myPathName);
  487.             FSMakeFSSpec(0, 0L, c2pstr(myPathName), &myFSSpec);
  488.             VRScript_SetCurrentDirectory(&myFSSpec);
  489.             break;
  490.         }
  491.         
  492.         case kSetBarState:                 // show or hide the controller bar
  493.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  494.             VRScript_SetControllerBarState(theWindowObject, (Boolean)myUInt32, myOptions);
  495.             break;
  496.         
  497.         case kSetButtonState: {             // show or hide a button in the controller bar;
  498.             UInt32        myButton;        // or, enable or disable the display text in the bar
  499.             
  500.              // NOTE: the semantics of the custom controller button are reversed from the others: you need to
  501.              // ask VRScript to *hide* the button (myState == 0) if you want it to appear; I might fix this at
  502.              // some point in the future....
  503.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myButton, &myUInt32, &myOptions);
  504.             VRScript_SetControllerButtonState(theWindowObject, myButton, (Boolean)myUInt32, myOptions);
  505.             break;
  506.         }
  507.         
  508.         case kSetResizeState:             // enable or disable window resizing
  509.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  510.             VRScript_SetResizeState(theWindowObject, (Boolean)myUInt32, myOptions);
  511.             break;
  512.         
  513.         case kSetWindowSize: {             // set the current size of a movie window
  514.             UInt32                myHeight;
  515.             UInt32                myWidth;
  516.             Rect                myRect;
  517.             MovieController     myMC;
  518.             
  519.             if (theWindowObject == NULL)
  520.                 break;
  521.                 
  522.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHeight, &myWidth, &myOptions);
  523.             myMC = (**theWindowObject).fController;
  524.             if (QTUtils_IsControllerBarVisible(myMC)) {
  525.                 MCGetControllerBoundsRect(myMC, &myRect);
  526.              } else {
  527.                 Movie    myMovie;
  528.                 
  529.                 myMovie = MCGetMovie(myMC);
  530.                 GetMovieBox(myMovie, &myRect);
  531.             }
  532.  
  533.             myRect.right = (short)myWidth;
  534.             myRect.bottom = (short)myHeight;
  535.             MCSetControllerBoundsRect(myMC, &myRect);
  536.             break;
  537.         }
  538.         
  539.         case kSetMaxWindowSize: {         // set the maximum size of a movie window
  540.             UInt32                myHeight;
  541.             UInt32                myWidth;
  542.             
  543.             if (theWindowObject == NULL)
  544.                 break;
  545.                 
  546.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHeight, &myWidth, &myOptions);
  547.             gLimitRect.right = (short)myWidth;
  548.             gLimitRect.bottom = (short)myHeight;
  549.             VRScript_SetResizeState(theWindowObject, (**theWindowObject).fCanResizeWindow, myOptions);
  550.             break;
  551.         }
  552.         
  553.         case kReplaceCursor: {             // replace one cursor by another, or restore the original QTVR cursor
  554.             SInt32                myPrevID;
  555.             SInt32                myNewID;
  556.             QTVRCursorRecord    myCursorRec;
  557.             
  558.             if (theWindowObject == NULL)
  559.                 break;
  560.                 
  561.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myPrevID, &myNewID, &myOptions);
  562.  
  563.             myCursorRec.theType = (UInt16)myOptions;        // the type of cursor to replace
  564.             myCursorRec.rsrcID = (SInt16)myPrevID;            // the resource ID of cursor to replace
  565.             if (myOptions == kQTVRUseDefaultCursor) {
  566.                 myCursorRec.handle = NULL;
  567.             } else {
  568.                 myCursorRec.handle = (Handle)MacGetCursor((short)myNewID);
  569.                 if (myCursorRec.handle != NULL)
  570.                     DetachResource(myCursorRec.handle);
  571.             }
  572.             
  573.             QTVRReplaceCursor((**theWindowObject).fInstance, &myCursorRec);
  574.                 
  575.             // QTVRReplaceCursor makes a copy of the handle we pass it, so we can dispose of our handle;
  576.             // make sure not to dispose the handle if QTVR loaded it, however
  577.             if ((myCursorRec.handle != NULL) && (myOptions != kQTVRUseDefaultCursor))
  578.                 DisposeHandle(myCursorRec.handle);
  579.             
  580.             break;
  581.         }
  582.         
  583.         case kSetHotSpotIDCursors: {    // replace the triad of cursors for a hot spot specified by its ID; currently this works only for *undefined* hot spots
  584.             SInt32        myCurs1ID, myCurs2ID, myCurs3ID;    // resource IDs of the three replacement cursors
  585.  
  586.             if (theWindowObject == NULL)
  587.                 break;
  588.  
  589.             // read the command paramters    
  590.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld", &myNodeID, &myHotSpotID, &myCurs1ID, &myCurs2ID, &myCurs3ID, &myOptions);
  591.  
  592.             // enlist three ReplaceCursor calls for entering the hot spot: install new cursor triad
  593.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, myCurs3ID, kQTVRStdCursorType);
  594.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  595.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, myCurs2ID, kQTVRStdCursorType);
  596.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  597.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, myCurs1ID, kQTVRStdCursorType);
  598.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  599.  
  600.             // enlist three ReplaceCursor calls for leaving the hot spot: reinstall original cursor triad
  601.             // NOTE: this prevents the new cursor from appearing on other hot spots of the same type, and
  602.             // also works around a bug in QTVR 2.0.0 and 2.0.1: replacing a cursor by itself disposes of 
  603.             // the cursor and eventually might lead to a crash.
  604.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  605.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  606.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  607.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  608.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  609.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  610.  
  611.             // enlist three ReplaceCursor calls for leaving the node: reinstall original cursor triad
  612.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  613.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  614.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  615.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  616.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  617.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  618.  
  619.             break;
  620.         }
  621.         
  622.         case kSetHotSpotTypeCursors: {    // replace the triad of cursors for a hot spot specified by its type
  623.             char        myHotSpotType[kMaxOSTypeLength];
  624.             SInt32        myCurs1ID, myCurs2ID, myCurs3ID;    // resource IDs of the three replacement cursors
  625.             OSType        myType;
  626.  
  627.             if (theWindowObject == NULL)
  628.                 break;
  629.  
  630.             // read the command paramters    
  631.             sscanf(theCommandLine, "%*s %ld %s %ld %ld %ld %ld", &myNodeID, myHotSpotType, &myCurs1ID, &myCurs2ID, &myCurs3ID, &myOptions);
  632.             
  633.             // convert the string to an OSType
  634.             myType = VRScript_StringToOSType(myHotSpotType);
  635.             
  636.             // enlist three ReplaceCursor calls for entering the hot spot: install new cursor triad
  637.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, myCurs3ID, kQTVRStdCursorType);
  638.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  639.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, myCurs2ID, kQTVRStdCursorType);
  640.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  641.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, myCurs1ID, kQTVRStdCursorType);
  642.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  643.  
  644.             // enlist three ReplaceCursor calls for leaving the hot spot: reinstall original cursor triad
  645.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  646.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  647.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  648.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  649.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  650.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  651.  
  652.             // enlist three ReplaceCursor calls for leaving the node: reinstall original cursor triad
  653.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  654.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  655.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  656.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  657.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  658.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  659.  
  660.             break;
  661.         }
  662.         
  663.         case kGoToNodeID:                 // go to a node        
  664.             if (theWindowObject == NULL)
  665.                 break;
  666.                 
  667.             sscanf(theCommandLine, "%*s %ld %ld", &myNodeID, &myOptions);
  668.             QTVRGoToNodeID((**theWindowObject).fInstance, myNodeID);
  669.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  670.             break;
  671.         
  672.         case kShowDefaultView:             // display the default view of the current node        
  673.             if (theWindowObject == NULL)
  674.                 break;
  675.                 
  676.             QTVRShowDefaultView((**theWindowObject).fInstance);
  677.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  678.             break;
  679.         
  680.         case kOpenResourceFile:             // open the specified resource file
  681.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  682.             VRScript_UnpackString(myPathName);
  683.             VRScript_OpenResourceFile(theWindowObject, myOptions, myPathName);
  684.             break;
  685.         
  686.         case kSetCorrection:            // set the imaging correction mode
  687.             if (theWindowObject == NULL)
  688.                 break;
  689.                 
  690.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  691.             QTVRSetImagingProperty((**theWindowObject).fInstance, (QTVRImagingMode)myOptions, kQTVRImagingCorrection, myUInt32);
  692.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  693.             break;
  694.         
  695.         case kSetQuality:                // set the image quality
  696.             if (theWindowObject == NULL)
  697.                 break;
  698.                 
  699.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  700.             QTVRSetImagingProperty((**theWindowObject).fInstance, (QTVRImagingMode)myOptions, kQTVRImagingQuality, myUInt32);
  701.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  702.             break;
  703.         
  704.         case kSetSwingSpeed:             // set the speed of swing transitions
  705.             if (theWindowObject == NULL)
  706.                 break;
  707.                 
  708.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  709.             QTVRSetTransitionProperty((**theWindowObject).fInstance, kQTVRTransitionSwing, kQTVRTransitionSpeed, myUInt32);
  710.             break;
  711.         
  712.         case kSetSwingDirection:         // set the direction of swing transitions
  713.             if (theWindowObject == NULL)
  714.                 break;
  715.                 
  716.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  717.             QTVRSetTransitionProperty((**theWindowObject).fInstance, kQTVRTransitionSwing, kQTVRTransitionDirection, myUInt32);
  718.             break;
  719.         
  720.         case kSetSwingState:            // enable or disable swing transitions
  721.             if (theWindowObject == NULL)
  722.                 break;
  723.                 
  724.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  725.             QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, (Boolean)myUInt32);
  726.             break;
  727.         
  728.         case kSetPanAngle:                 // set the pan angle
  729.             if (theWindowObject == NULL)
  730.                 break;
  731.                 
  732.             sscanf(theCommandLine, "%*s %f %ld", &myPanAngle, &myOptions);
  733.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  734.             
  735.             if (myOptions == kVRValue_Relative) {
  736.                 myTempAngle = QTVRGetPanAngle((**theWindowObject).fInstance);
  737.                 myPanAngle += myTempAngle;
  738.             }
  739.             
  740.             QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  741.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  742.             break;
  743.         
  744.         case kSetTiltAngle:                // set the tilt angle
  745.             if (theWindowObject == NULL)
  746.                 break;
  747.                 
  748.             sscanf(theCommandLine, "%*s %f %ld", &myTiltAngle, &myOptions);
  749.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  750.             
  751.             if (myOptions == kVRValue_Relative) {
  752.                 myTempAngle = QTVRGetTiltAngle((**theWindowObject).fInstance);
  753.                 myTiltAngle += myTempAngle;
  754.             }
  755.             
  756.             QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  757.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  758.             break;
  759.         
  760.         case kSetPanTiltZoom:             // set the pan, tilt, and zoom angles
  761.             if (theWindowObject == NULL)
  762.                 break;
  763.                 
  764.             sscanf(theCommandLine, "%*s %f %f %f %ld %ld", &myPanAngle, &myTiltAngle, &myFOVAngle, &myUInt32, &myOptions);
  765.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  766.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  767.             myFOVAngle = QTVRUtils_DegreesToRadians(myFOVAngle);
  768.             
  769.             if (myOptions == kVRValue_Relative) {
  770.                 myTempAngle = QTVRGetPanAngle((**theWindowObject).fInstance);
  771.                 myPanAngle += myTempAngle;
  772.                 myTempAngle = QTVRGetTiltAngle((**theWindowObject).fInstance);
  773.                 myTiltAngle += myTempAngle;
  774.                 myTempAngle = QTVRGetFieldOfView((**theWindowObject).fInstance);
  775.                 myFOVAngle += myTempAngle;
  776.             }
  777.             
  778.             // enable swing transitions, if requested by myMode parameter
  779.             if ((myUInt32 == kVRTransition_Swing) || (myUInt32 == kVRTransition_SwingWait))
  780.                 QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, true);
  781.             
  782.             // set the desired FOV, pan, and tilt angles
  783.             QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  784.             QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  785.             QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  786.  
  787.             // update the screen
  788.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  789.  
  790.             // if a blocking swing is requested, "spin our wheels" until we get (close to) to the destination angles
  791.             if (myUInt32 == kVRTransition_SwingWait)
  792.                 while (!VRScript_FloatsAreEqual(myPanAngle, QTVRGetPanAngle((**theWindowObject).fInstance), kRadianTolerance) ||
  793.                        !VRScript_FloatsAreEqual(myTiltAngle, QTVRGetTiltAngle((**theWindowObject).fInstance), kRadianTolerance) ||
  794.                        !VRScript_FloatsAreEqual(myFOVAngle, QTVRGetFieldOfView((**theWindowObject).fInstance), kRadianTolerance)) {
  795.                        
  796.                     QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  797.                     QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  798.                     QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  799.                     
  800.                     DoIdle((**theWindowObject).fWindow); 
  801.                     MCIdle((**theWindowObject).fController); 
  802.                 }
  803.  
  804.             // disable swing transitions, if previously enabled
  805.             if ((myUInt32 == kVRTransition_Swing) || (myUInt32 == kVRTransition_SwingWait))
  806.                 QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, false);
  807.                 
  808.             break;
  809.         
  810.         case kSetFieldOfView:             // set the field of view
  811.             if (theWindowObject == NULL)
  812.                 break;
  813.                 
  814.             sscanf(theCommandLine, "%*s %f %ld", &myFOVAngle, &myOptions);
  815.             myFOVAngle = QTVRUtils_DegreesToRadians(myFOVAngle);
  816.             
  817.             if (myOptions == kVRValue_Relative) {
  818.                 myTempAngle = QTVRGetFieldOfView((**theWindowObject).fInstance);
  819.                 myFOVAngle += myTempAngle;
  820.             }
  821.             
  822.             QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  823.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  824.             break;
  825.         
  826.         case kSetViewCenter: {             // set the view center of an object node
  827.             QTVRFloatPoint        myPoint;
  828.             
  829.             if (theWindowObject == NULL)
  830.                 break;
  831.                 
  832.             sscanf(theCommandLine, "%*s %f %f %ld", &myPoint.x, &myPoint.y, &myOptions);
  833.             QTVRSetViewCenter((**theWindowObject).fInstance, &myPoint);
  834.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  835.             break;
  836.         }
  837.         
  838.         case kSetPanLimits:                 // set the current pan angle constraints
  839.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  840.             VRScript_SetAngleConstraints(theWindowObject, kQTVRPan, myMinAngle, myMaxAngle, myOptions);
  841.             break;
  842.         
  843.         case kSetTiltLimits:             // set the current tilt angle constraints
  844.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  845.             VRScript_SetAngleConstraints(theWindowObject, kQTVRTilt, myMinAngle, myMaxAngle, myOptions);
  846.             break;
  847.         
  848.         case kSetZoomLimits:             // set the current zoom angle constraints
  849.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  850.             VRScript_SetAngleConstraints(theWindowObject, kQTVRFieldOfView, myMinAngle, myMaxAngle, myOptions);
  851.             break;
  852.         
  853.         case kSetHotSpotState: {         // enable or disable a hot spot;
  854.             UInt32        myState;        // there's no easy way to get the current state of a hot spot, so we don't support toggling
  855.  
  856.             if (theWindowObject == NULL)
  857.                 break;
  858.                 
  859.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHotSpotID, &myState, &myOptions);
  860.             QTVREnableHotSpot((**theWindowObject).fInstance, myOptions, myHotSpotID, (Boolean)myState);
  861.             
  862.             // we need to update, because the hot spot regions might currently be showing
  863.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  864.  
  865.             break;
  866.         }
  867.         
  868.         case kSetTranslateState:         // enable or disable object translation
  869.             if (theWindowObject == NULL)
  870.                 break;
  871.                 
  872.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  873.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionTranslateOnMouseDown, (void *)myUInt32);
  874.             break;
  875.         
  876.         case kSetClickRadius: {             // set the radius within which clicks occur
  877.             UInt16        myRadius;
  878.  
  879.             if (theWindowObject == NULL)
  880.                 break;
  881.                 
  882.             sscanf(theCommandLine, "%*s %ld %ld", &myRadius, &myOptions);
  883.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseClickHysteresis, (void *)myRadius);
  884.             break;
  885.         }
  886.         
  887.         case kSetClickTimeout:             // set the timeout for clicks
  888.             if (theWindowObject == NULL)
  889.                 break;
  890.                 
  891.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  892.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseClickTimeout, (void *)myUInt32);
  893.             break;
  894.         
  895.         case kSetPanTiltSpeed:             // set the pan and tilt speed
  896.             if (theWindowObject == NULL)
  897.                 break;
  898.                 
  899.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  900.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionPanTiltSpeed, (void *)myUInt32);
  901.             break;
  902.         
  903.         case kSetZoomSpeed:                 // set the zoom speed
  904.             if (theWindowObject == NULL)
  905.                 break;
  906.                 
  907.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  908.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionZoomSpeed, (void *)myUInt32);
  909.             break;
  910.         
  911.         case kSetMouseScale:             // set the mouse-motion scale
  912.             if (theWindowObject == NULL)
  913.                 break;
  914.                 
  915.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  916.             myFloat = QTVRUtils_DegreesToRadians(myFloat);
  917.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseMotionScale, &myFloat);
  918.             break;
  919.         
  920.         case kSetFrameRate:                 // set the frame rate of an object node
  921.             if (theWindowObject == NULL)
  922.                 break;
  923.                 
  924.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  925.  
  926.             if (myOptions == kVRValue_Relative)
  927.                 myFloat += QTVRGetFrameRate((**theWindowObject).fInstance);
  928.             
  929.             QTVRSetFrameRate((**theWindowObject).fInstance, myFloat);
  930.             break;
  931.         
  932.         case kSetViewRate:                 // set the view rate of an object node
  933.             if (theWindowObject == NULL)
  934.                 break;
  935.                 
  936.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  937.             
  938.             if (myOptions == kVRValue_Relative)
  939.                 myFloat += QTVRGetViewRate((**theWindowObject).fInstance);
  940.             
  941.             QTVRSetViewRate((**theWindowObject).fInstance, myFloat);
  942.             break;
  943.         
  944.         case kSetViewTime: {             // set the current view time of an object node
  945.             TimeValue    myTime;
  946.  
  947.             if (theWindowObject == NULL)
  948.                 break;
  949.                 
  950.             sscanf(theCommandLine, "%*s %f %ld", &myTime, &myOptions);
  951.             
  952.             if (myOptions == kVRValue_Relative)
  953.                 myTime += QTVRGetViewCurrentTime((**theWindowObject).fInstance);
  954.             
  955.             QTVRSetViewCurrentTime((**theWindowObject).fInstance, myTime);
  956.             break;
  957.         }
  958.         
  959.         case kSetViewState: {             // set the current view state of an object node
  960.             UInt32        myType;
  961.             UInt32        myState;
  962.  
  963.             if (theWindowObject == NULL)
  964.                 break;
  965.                 
  966.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myType, &myState, &myOptions);
  967.             QTVRSetViewState((**theWindowObject).fInstance, (QTVRViewStateType)myType, (UInt16)myState);
  968.             break;
  969.         }
  970.         
  971.         case kSetAnimationState: {         // set the animation state of an object node
  972.             UInt32        mySetting;
  973.             UInt32        myState;
  974.  
  975.             if (theWindowObject == NULL)
  976.                 break;
  977.                 
  978.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySetting, &myState, &myOptions);
  979.             QTVRSetAnimationSetting((**theWindowObject).fInstance, (QTVRObjectAnimationSetting)mySetting, (Boolean)myState);
  980.             break;
  981.         }
  982.         
  983.         case kSetControlState: {         // set the control state of an object node
  984.             UInt32        mySetting;
  985.             UInt32        myState;
  986.  
  987.             if (theWindowObject == NULL)
  988.                 break;
  989.                 
  990.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySetting, &myState, &myOptions);
  991.             QTVRSetControlSetting((**theWindowObject).fInstance, (QTVRControlSetting)mySetting, (Boolean)myState);
  992.             break;
  993.         }
  994.         
  995.         case kSetFrameAnimState:         // enable or disable frame animation in an object node
  996.             if (theWindowObject == NULL)
  997.                 break;
  998.                 
  999.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1000.             QTVREnableFrameAnimation((**theWindowObject).fInstance, (Boolean)myUInt32);
  1001.             break;
  1002.         
  1003.         case kSetViewAnimState:             // enable or disable view animation in an object node
  1004.             if (theWindowObject == NULL)
  1005.                 break;
  1006.                 
  1007.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1008.             QTVREnableViewAnimation((**theWindowObject).fInstance, (Boolean)myUInt32);
  1009.             break;
  1010.         
  1011.         case kSetQTVRVisState:             // enable or disable QTVR movie visibility
  1012.             if (theWindowObject == NULL)
  1013.                 break;
  1014.                 
  1015.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1016.             QTVRSetVisible((**theWindowObject).fInstance, (Boolean)myUInt32);
  1017.             break;
  1018.         
  1019.         case kSetCachePrefs: {             // set the back buffer resolution, depth, and size
  1020.             SInt32        myResolution;
  1021.             SInt32        myDepth;
  1022.             SInt32        mySize;
  1023.  
  1024.             if (theWindowObject == NULL)
  1025.                 break;
  1026.                 
  1027.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myResolution, &myDepth, &mySize, &myOptions);
  1028.             QTVRSetBackBufferPrefs((**theWindowObject).fInstance, kQTVRUseMovieGeometry, (UInt16)myResolution, (SInt16)myDepth, (SInt16)mySize);
  1029.             break;
  1030.         }
  1031.         
  1032.         case kSetMovieVolume:             // set the volume of a QTVR sound track
  1033.             if (theWindowObject == NULL)
  1034.                 break;
  1035.                 
  1036.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1037.             SetMovieVolume((**theWindowObject).fMovie, (short)myUInt32);
  1038.             break;
  1039.         
  1040.         case kSetSoundVolume: {             // set the volume of a sound
  1041.             UInt32                myVolume;
  1042.             VRScriptSoundPtr    mySoundPtr;
  1043.             VRScriptMoviePtr    myMoviePtr;
  1044.  
  1045.             if (theWindowObject == NULL)
  1046.                 break;
  1047.                 
  1048.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myVolume, &myOptions);
  1049.             
  1050.             // is it a sound resource?
  1051.             mySoundPtr = (VRScriptSoundPtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_Sound, myEntryID);
  1052.             if (mySoundPtr != NULL) {
  1053.                 VRSound_SetVolume(mySoundPtr->fChannel, (unsigned short)myVolume, (unsigned short)myVolume);
  1054.                 break;
  1055.             }
  1056.             
  1057.             // is it a movie sound track?
  1058.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1059.             if (myMoviePtr != NULL)
  1060.                 SetMovieVolume(myMoviePtr->fMovie, (short)myVolume);
  1061.  
  1062.             break;
  1063.         }
  1064.         
  1065.         case kSetSoundBalance: {         // set the balance of a sound
  1066.             UInt32                myLeftPct;
  1067.             UInt32                myRightPct;
  1068.             VRScriptSoundPtr    mySoundPtr;
  1069.             VRScriptMoviePtr    myMoviePtr;
  1070.             unsigned short        myLeftVol, myRightVol;
  1071.  
  1072.             if (theWindowObject == NULL)
  1073.                 break;
  1074.                 
  1075.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myEntryID, &myLeftPct, &myRightPct, &myOptions);
  1076.             
  1077.             // is it a sound resource?
  1078.             mySoundPtr = (VRScriptSoundPtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_Sound, myEntryID);
  1079.             if (mySoundPtr != NULL) {
  1080.                 VRSound_GetVolume(mySoundPtr->fChannel, &myLeftVol, &myRightVol);
  1081.                 VRSound_SetVolume(mySoundPtr->fChannel, myLeftVol * (myLeftPct / 100), myRightVol * (myRightPct / 100));
  1082.                 break;
  1083.             }
  1084.             
  1085.             // is it a movie sound track?
  1086.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1087.             if (myMoviePtr != NULL) {
  1088.                 short            myValue;
  1089.                 
  1090.                 myValue = (((float)myRightPct / 100) * kQTMaxSoundVolume) - (((float)myLeftPct / 100) * kQTMaxSoundVolume);
  1091.                 MediaSetSoundBalance(myMoviePtr->fMediaHandler, myValue);
  1092.             }
  1093.             
  1094.             break;
  1095.         }
  1096.         
  1097.         case kPlaySceneSound: {            // play a movie-wide ambient sound asynchronously
  1098.              UInt32        myMode;
  1099.              UInt32        myFade;
  1100.  
  1101.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myMode, &myFade, &myOptions);
  1102.             VRSound_PlaySound(theWindowObject, kVRAnyNode, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1103.             break;
  1104.         }
  1105.         
  1106.         case kPlaySceneQTMidi: {        // play a movie-wide ambient QuickTime sound-only file asynchronously
  1107.             UInt32        myMode;
  1108.              UInt32        myFade;
  1109.              UInt32        myIsLocal;
  1110.             float        myX, myY, myZ;
  1111.             float        myProjAngle;
  1112.         
  1113.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %s", &myEntryID, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1114.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1115.             VRMoov_PlayMovie(theWindowObject, kVRAnyNode, myEntryID, QTVRUtils_Point3DToPanAngle(myX, myY, myZ), QTVRUtils_Point3DToTiltAngle(myX, myY, myZ), 0.0, 0.0, 0.0, 0.0, 0.0, false, false, false, false, myIsLocal, myIsLocal, myProjAngle, myMode, myOptions, myPathName);
  1116.             break;
  1117.         }
  1118.         
  1119.         case kPlayNodeQTMidi: {             // play a QuickTime MIDI file in a node
  1120.             UInt32        myMode;
  1121.             UInt32        myFade;
  1122.              UInt32        myIsLocal;
  1123.             float        myX, myY, myZ;
  1124.             float        myProjAngle;
  1125.             
  1126.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %s", &myNodeID, &myEntryID, &myMaxTimes, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1127.             sprintf(myCmdLine, "PlayQTMidi %ld %ld %f %f %f %f %ld %ld %ld %s", myEntryID, myIsLocal, myX, myY, myZ, myProjAngle, myMode, myFade, myOptions, myPathName);
  1128.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1129.             break;
  1130.         }
  1131.         
  1132.         case kPlayNodeSound: {             // play a sound in a node
  1133.             UInt32        myMode;
  1134.             UInt32        myFade;
  1135.  
  1136.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myEntryID, &myMaxTimes, &myMode, &myFade, &myOptions);
  1137.             sprintf(myCmdLine, "PlaySndResource %ld %ld %ld %ld %ld", myResID, myEntryID, myMode, myFade, myOptions);
  1138.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1139.             break;
  1140.         }
  1141.         
  1142.         case kPlayNode3DSound: {         // play a 3D sound in a node
  1143.             float        myX, myY, myZ;
  1144.             float        myProjAngle;
  1145.             UInt32        mySourceMode;
  1146.             UInt32        myMode;
  1147.             UInt32        myFade;
  1148.  
  1149.             sscanf(theCommandLine, "%*s %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMaxTimes, &myMode, &myFade, &myOptions);
  1150.             sprintf(myCmdLine, "Play3DSndResource %ld %ld %f %f %f %f %ld %ld %ld %ld", myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1151.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1152.             break;
  1153.         }
  1154.         
  1155.         case kHotSpotQTMidi: {             // play a QuickTime MIDI file when a hot spot is clicked
  1156.             UInt32        myMode;
  1157.             UInt32        myFade;
  1158.              UInt32        myIsLocal;
  1159.             float        myX, myY, myZ;
  1160.             float        myProjAngle;
  1161.             
  1162.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myEntryID, &myMaxTimes, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1163.             sprintf(myCmdLine, "PlayQTMidi %ld %ld %f %f %f %f %ld %ld %ld %s", myEntryID, myIsLocal, myX, myY, myZ, myProjAngle, myMode, myFade, myOptions, myPathName);
  1164.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1165.             break;
  1166.         }
  1167.         
  1168.         case kHotSpotSound: {             // play a sound when a hot spot is clicked
  1169.             UInt32        myMode;
  1170.             UInt32        myFade;
  1171.  
  1172.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myHotSpotID, &myEntryID, &myMaxTimes, &myMode, &myFade, &myOptions);
  1173.             sprintf(myCmdLine, "PlaySndResource %ld %ld %ld %ld %ld", myResID, myEntryID, myMode, myFade, myOptions);
  1174.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1175.             break;
  1176.         }
  1177.         
  1178.         case kHotSpot3DSound: {             // play a 3D sound when a hot spot is clicked
  1179.             float        myX, myY, myZ;
  1180.             float        myProjAngle;
  1181.             UInt32        mySourceMode;
  1182.             UInt32        myMode;
  1183.             UInt32        myFade;
  1184.  
  1185.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myHotSpotID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMaxTimes, &myMode, &myFade, &myOptions);
  1186.             sprintf(myCmdLine, "Play3DSndResource %ld %ld %f %f %f %f %ld %ld %ld %ld", myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1187.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1188.             break;
  1189.         }
  1190.         
  1191.         case kHotSpotMovie: {             // play a movie when a hot spot is clicked
  1192.              float        myScale;
  1193.              float        myWidth;
  1194.              UInt32        myKeyRed;
  1195.              UInt32        myKeyGreen;
  1196.              UInt32        myKeyBlue;
  1197.             UInt32        myUseBuffer;
  1198.             UInt32        myUseCenter;
  1199.             UInt32        myUseKey;
  1200.             UInt32        myUseHide;
  1201.             UInt32        myUseDir;
  1202.             UInt32        myRotate;
  1203.              float        myVolAngle;
  1204.             UInt32        myMode;
  1205.  
  1206.             sscanf(theCommandLine, "%*s %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %ld %s", 
  1207.                     &myEntryID, 
  1208.                     &myNodeID, 
  1209.                     &myHotSpotID, 
  1210.                     &myPanAngle,
  1211.                     &myTiltAngle,
  1212.                     &myScale, 
  1213.                     &myWidth, 
  1214.                     &myKeyRed, 
  1215.                     &myKeyGreen, 
  1216.                     &myKeyBlue, 
  1217.                     &myUseBuffer,
  1218.                     &myUseCenter,
  1219.                     &myUseKey,
  1220.                     &myUseHide,
  1221.                     &myUseDir,
  1222.                     &myRotate,
  1223.                     &myVolAngle,
  1224.                     &myMaxTimes,
  1225.                     &myMode,
  1226.                     &myOptions,
  1227.                     myPathName);
  1228.                 
  1229.             sprintf(myCmdLine, "PlayMovie %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %s",
  1230.                     myEntryID,
  1231.                     myPanAngle,
  1232.                     myTiltAngle,
  1233.                     myScale, 
  1234.                     myWidth, 
  1235.                     myKeyRed, 
  1236.                     myKeyGreen, 
  1237.                     myKeyBlue, 
  1238.                     (Boolean)myUseBuffer,
  1239.                     (Boolean)myUseCenter,
  1240.                     (Boolean)myUseKey,
  1241.                     (Boolean)myUseHide,
  1242.                     (Boolean)myUseDir,
  1243.                     (Boolean)myRotate,
  1244.                     myVolAngle,
  1245.                     myMode,
  1246.                     myOptions,
  1247.                     myPathName);
  1248.  
  1249.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1250.             break;
  1251.         }
  1252.         
  1253.         case kTriggerHotSpot:             // trigger a particular hot spot
  1254.             if (theWindowObject == NULL)
  1255.                 break;
  1256.                 
  1257.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1258.             QTVRTriggerHotSpot((**theWindowObject).fInstance, myUInt32, 0, 0);
  1259.             break;
  1260.         
  1261.         case kPlayQTMidi: {                // play a QuickTime sound-only file asynchronously, or stop a file from playing
  1262.             UInt32        myMode;
  1263.              UInt32        myFade;
  1264.              UInt32        myIsLocal;
  1265.             float        myX, myY, myZ;
  1266.             float        myProjAngle;
  1267.         
  1268.             if (theWindowObject == NULL)
  1269.                 break;
  1270.                 
  1271.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1272.  
  1273.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %s", &myEntryID, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1274.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1275.             VRMoov_PlayMovie(theWindowObject, myNodeID, myEntryID, QTVRUtils_Point3DToPanAngle(myX, myY, myZ), QTVRUtils_Point3DToTiltAngle(myX, myY, myZ), 0.0, 0.0, 0.0, 0.0, 0.0, false, false, false, false, myIsLocal, myIsLocal, myProjAngle, myMode, myOptions, myPathName);
  1276.             break;
  1277.         }
  1278.         
  1279.         case kPlaySndResource: {        // play a sound resource ambiently, or stop an ambient sound resource from playing
  1280.              UInt32        myMode;
  1281.              UInt32        myFade;
  1282.  
  1283.             if (theWindowObject == NULL)
  1284.                 break;
  1285.             
  1286.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1287.             
  1288.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myMode, &myFade, &myOptions);
  1289.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1290.             break;
  1291.         }
  1292.         
  1293.         case kPlaySoundFile: {            // play a sound file ambiently, or stop an ambient sound file from playing
  1294.              UInt32        myMode;
  1295.              UInt32        myFade;
  1296.             short        myRefNum;
  1297.             short        myResID;
  1298.  
  1299.             if (theWindowObject == NULL)
  1300.                 break;
  1301.             
  1302.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1303.             
  1304.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myEntryID, &myMode, &myFade, &myOptions, myPathName);
  1305.             
  1306.             // a sound file (of type 'sfil') is a resource file that contains one 'snd ' resource,
  1307.             // so open the resource file and get the resource ID; then call VRSound_PlaySound.
  1308.             myRefNum = VRScript_OpenResourceFile(theWindowObject, 0, myPathName);
  1309.             myResID = VRSound_GetSndResourceID(myRefNum);
  1310.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1311.             break;
  1312.         }
  1313.         
  1314.         case kPlay3DSndResource: {        // play a sound file localized, or stop an ambient sound file from playing
  1315.             float        myX, myY, myZ;
  1316.             float        myProjAngle;
  1317.             UInt32        mySourceMode;
  1318.              UInt32        myMode;
  1319.             UInt32        myFade;
  1320.  
  1321.             if (theWindowObject == NULL)
  1322.                 break;
  1323.  
  1324.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1325.             
  1326.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %ld", &myResID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMode, &myFade, &myOptions);
  1327.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1328.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1329.             break;
  1330.         }
  1331.         
  1332.         case kPlay3DSndResourceAngle: {    // play a localized sound, specified using angles
  1333.             TQ3Point3D    myPoint;
  1334.             float        myDistance;
  1335.             float        myProjAngle;
  1336.             UInt32        mySourceMode;
  1337.             UInt32        myMode;
  1338.             UInt32        myFade;
  1339.         
  1340.             if (theWindowObject == NULL)
  1341.                 break;
  1342.  
  1343.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1344.             
  1345.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld", &myResID, &myEntryID, &myPanAngle, &myTiltAngle, &myDistance, &myProjAngle, &mySourceMode, &myMode, &myFade, &myOptions);
  1346.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  1347.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  1348.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1349.  
  1350.             myPoint.x = -sin(myPanAngle) * cos(myTiltAngle) * (myDistance);
  1351.             myPoint.y = sin(myTiltAngle) * (myDistance);
  1352.             myPoint.z = -cos(myPanAngle) * cos(myTiltAngle) * (myDistance);
  1353.  
  1354.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, myPoint.x, myPoint.y, myPoint.z, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1355.             break;
  1356.         }
  1357.         
  1358.         case kShowPicture: {            // overlay a picture (in the front buffer)
  1359.             UInt32        myHeight;
  1360.             UInt32        myWidth;
  1361.             UInt32        myPegSides;
  1362.             UInt32        myOffset;
  1363.  
  1364.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myHeight, &myWidth, &myPegSides, &myOffset, &myOptions);
  1365.             VRPicture_ShowPicture(theWindowObject, myResID, myEntryID, myHeight, myWidth, myPegSides, myOffset, myOptions);
  1366.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1367.             break;
  1368.         }
  1369.         
  1370.         case kShowNodePicture: {         // overlay a picture (in the front buffer) in a particular node
  1371.             UInt32        myHeight;
  1372.             UInt32        myWidth;
  1373.             UInt32        myPegSides;
  1374.             UInt32        myOffset;
  1375.  
  1376.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myNodeID, &myHeight, &myWidth, &myPegSides, &myOffset, &myOptions);
  1377.             sprintf(myCmdLine, "ShowPicture %ld %ld %ld %ld %ld %ld %ld", myResID, myEntryID, myHeight, myWidth, myPegSides, myOffset, myOptions);
  1378.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, kVRDoIt_Forever, 0, myCmdLine);
  1379.             break;
  1380.         }
  1381.         
  1382.          case kAtTime: {                     // execute a command at a specific time
  1383.             UInt32        myTicks;
  1384.             UInt32        myMode;
  1385.             UInt32        myRepeat;
  1386.             UInt32        myPeriod;
  1387.             
  1388.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %s", &myTicks, &myMode, &myNodeID, &myRepeat, &myPeriod, &myMaxTimes, &myOptions, myCmdLine);
  1389.             VRScript_UnpackString(myCmdLine);
  1390.             VRScript_EnlistTimedCommand(theWindowObject, myTicks, myMode, myNodeID, myRepeat, myPeriod, myMaxTimes, myOptions, myCmdLine);
  1391.             break;
  1392.         }
  1393.         
  1394.          case kAtAppLaunch:                 // execute a command when the application is launched
  1395.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myCmdLine);
  1396.             VRScript_UnpackString(myCmdLine);
  1397.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine);
  1398.             break;
  1399.         
  1400.          case kAtAppQuit:                 // execute a command when the application is quit
  1401.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myCmdLine);
  1402.             VRScript_UnpackString(myCmdLine);
  1403.             VRScript_EnlistQuitCommand(theWindowObject, myOptions, myCmdLine);
  1404.             break;
  1405.         
  1406.          case kAtMouseOverHSID:             // execute a command when the mouse is over a hot spot, targeted by ID
  1407.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myMaxTimes, &myOptions, myCmdLine);
  1408.             VRScript_UnpackString(myCmdLine);
  1409.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, myOptions, myCmdLine);
  1410.             break;
  1411.         
  1412.          case kAtMouseOverHSType: {         // execute a command when the mouse is over a hot spot, targeted by type
  1413.             OSType        myType;
  1414.             char        myHotSpotType[kMaxOSTypeLength];
  1415.                     
  1416.             sscanf(theCommandLine, "%*s %ld %s %ld %ld %s", &myNodeID, &myHotSpotType, &myMaxTimes, &myOptions, myCmdLine);
  1417.             myType = VRScript_StringToOSType(myHotSpotType);
  1418.             
  1419.             VRScript_UnpackString(myCmdLine);
  1420.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, myMaxTimes, myOptions, myCmdLine);
  1421.             break;
  1422.         }
  1423.         
  1424.          case kAtClickHSID:                 // execute a command when the mouse is clicked on a hot spot, targeted by ID
  1425.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myMaxTimes, &myOptions, myCmdLine);
  1426.             VRScript_UnpackString(myCmdLine);
  1427.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, myOptions, myCmdLine);
  1428.             break;
  1429.         
  1430.          case kAtClickHSType: {             // execute a command when the mouse is clicked on a hot spot, targeted by type
  1431.             OSType        myType;
  1432.             char        myHotSpotType[kMaxOSTypeLength];
  1433.                     
  1434.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotType, &myMaxTimes, &myOptions, myCmdLine);
  1435.             myType = VRScript_StringToOSType(myHotSpotType);
  1436.  
  1437.             VRScript_UnpackString(myCmdLine);
  1438.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, myMaxTimes, myOptions, myCmdLine);
  1439.             break;
  1440.         }
  1441.         
  1442.          case kAtClickCustomButton:        // execute a command when the mouse is clicked on the custom button in the controller bar
  1443.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1444.             VRScript_UnpackString(myCmdLine);
  1445.             VRScript_EnlistClickCustomButtonCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1446.             break;
  1447.         
  1448.          case kAtClickSprite:            // execute a command when the mouse is clicked on a sprite            
  1449.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1450.             VRScript_UnpackString(myCmdLine);
  1451.             VRScript_EnlistClickSpriteCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1452.             break;
  1453.         
  1454.          case kAtNodeEntry:                 // execute a command when the specified node is entered
  1455.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1456.             VRScript_UnpackString(myCmdLine);
  1457.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1458.             break;
  1459.         
  1460.          case kAtNodeExit: {                 // execute a command when the specified node is exited
  1461.             UInt32        myFromNodeID;
  1462.             UInt32        myToNodeID;
  1463.             
  1464.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myFromNodeID, &myToNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1465.             VRScript_UnpackString(myCmdLine);
  1466.             VRScript_EnlistNodeExitCommand(theWindowObject, myFromNodeID, myToNodeID, myMaxTimes, myOptions, myCmdLine);
  1467.             break;
  1468.         }
  1469.         
  1470.          case kAtPanAngle:                 // execute a command at the specified pan angle
  1471.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1472.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_PanAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1473.             break;
  1474.         
  1475.          case kAtTiltAngle:                 // execute a command at the specified tilt angle
  1476.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1477.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_TiltAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1478.             break;
  1479.         
  1480.          case kAtZoomAngle:                 // execute a command at the specified zoom angle
  1481.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1482.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_FOVAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1483.             break;
  1484.         
  1485.          case kDoBoth: {                     // execute both of the specified commands
  1486.             char        myCmdLine1[kMaxCmdLineLength];
  1487.             char        myCmdLine2[kMaxCmdLineLength];
  1488.  
  1489.             sscanf(theCommandLine, "%*s %ld %s %s", &myOptions, myCmdLine1, myCmdLine2);
  1490.             VRScript_UnpackString(myCmdLine1);
  1491.             VRScript_UnpackString(myCmdLine2);
  1492.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine1);
  1493.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine2);
  1494.             break;
  1495.         }
  1496.         
  1497.          case kDoNothing:                 // don't do anything; this can be useful to trigger some side effects of an "At" command
  1498.             break;
  1499.         
  1500.          case kPlayMovie: {                 // play a QuickTime movie
  1501.              float        myScale;
  1502.              float        myWidth;
  1503.              UInt32        myKeyRed;
  1504.              UInt32        myKeyGreen;
  1505.              UInt32        myKeyBlue;
  1506.             UInt32        myUseBuffer;
  1507.             UInt32        myUseCenter;
  1508.             UInt32        myUseKey;
  1509.             UInt32        myUseHide;
  1510.             UInt32        myUseDir;
  1511.             UInt32        myRotate;
  1512.             UInt32        myMode;
  1513.              float        myVolAngle;
  1514.             
  1515.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %s", 
  1516.                     &myEntryID,
  1517.                     &myPanAngle,
  1518.                     &myTiltAngle,
  1519.                     &myScale, 
  1520.                     &myWidth, 
  1521.                     &myKeyRed, 
  1522.                     &myKeyGreen, 
  1523.                     &myKeyBlue, 
  1524.                     &myUseBuffer,
  1525.                     &myUseCenter,
  1526.                     &myUseKey,
  1527.                     &myUseHide,
  1528.                     &myUseDir,
  1529.                     &myRotate,
  1530.                     &myVolAngle,
  1531.                     &myMode,
  1532.                     &myOptions,
  1533.                     myPathName);
  1534.                 
  1535.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  1536.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  1537.             myVolAngle = QTVRUtils_DegreesToRadians(myVolAngle);
  1538.             myWidth = QTVRUtils_DegreesToRadians(myWidth);
  1539.  
  1540.             if (theWindowObject == NULL)
  1541.                 break;
  1542.  
  1543.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1544.  
  1545.             VRScript_UnpackString(myPathName);
  1546.             VRMoov_PlayMovie(theWindowObject,
  1547.                     myNodeID,
  1548.                     myEntryID,
  1549.                     myPanAngle,
  1550.                     myTiltAngle,
  1551.                     myScale, 
  1552.                     myWidth, 
  1553.                     myKeyRed, 
  1554.                     myKeyGreen, 
  1555.                     myKeyBlue, 
  1556.                     (Boolean)myUseBuffer,
  1557.                     (Boolean)myUseCenter,
  1558.                     (Boolean)myUseKey,
  1559.                     (Boolean)myUseHide,
  1560.                     (Boolean)myUseDir,
  1561.                     (Boolean)myRotate,
  1562.                     myVolAngle,
  1563.                     myMode,
  1564.                     myOptions,
  1565.                     myPathName);
  1566.             break;
  1567.         }
  1568.         
  1569.          case kPlayTransMovie:             // play a QuickTime movie as a transition between two nodes
  1570.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  1571.             VRMoov_PlayTransitionMovie(theWindowObject, myOptions, myPathName);
  1572.             break;
  1573.         
  1574.          case kPlayTransEffect: {         // play a QuickTime video effect as a transition between two nodes
  1575.             char        myEffectType[kMaxOSTypeLength];
  1576.             UInt32        myFromNodeID;
  1577.             UInt32        myToNodeID;
  1578.             long        myEffectNum;
  1579.             OSType        myType;
  1580.             
  1581.             sscanf(theCommandLine, "%*s %ld %ld %ld %s %ld %ld", &myFromNodeID, &myToNodeID, &myMaxTimes, myEffectType, &myEffectNum, &myOptions);
  1582.  
  1583.             // convert the string to an OSType
  1584.             myType = VRScript_StringToOSType(myEffectType);
  1585.  
  1586.             VRScript_EnlistTransitionEffect(theWindowObject, myFromNodeID, myToNodeID, myMaxTimes, myType, myEffectNum, myOptions);
  1587.             break;
  1588.         }
  1589.         
  1590.         case kMoveScreen: {                 // shift the movie screen center
  1591.             QTVRFloatPoint    myCenter;
  1592.             float            myHoriz;
  1593.             float            myVert;
  1594.  
  1595.             sscanf(theCommandLine, "%*s %f %f %ld", &myHoriz, &myVert, &myOptions);
  1596.             myHoriz = QTVRUtils_DegreesToRadians(myHoriz);
  1597.             myVert = QTVRUtils_DegreesToRadians(myVert);
  1598.             VRMoov_GetEmbeddedMovieCenter(theWindowObject, &myCenter);
  1599.             myCenter.x += myHoriz;
  1600.             myCenter.y += myVert;
  1601.             VRMoov_SetEmbeddedMovieCenter(theWindowObject, &myCenter);
  1602.             break;
  1603.         }
  1604.         
  1605.         case kBeep:                        // play the system beep
  1606.             DoBeep();
  1607.             break;
  1608.         
  1609.         case kProcessScript:            // open and process a script file (synchronously!)
  1610.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  1611.             VRScript_OpenScriptFile(theWindowObject, myPathName);
  1612.             break;
  1613.         
  1614. #if QD3D_AVAIL
  1615.         case kCreateBox: {                 // create a box
  1616.             float        myX, myY, myZ;
  1617.             float        myXSize, myYSize, myZSize;
  1618.  
  1619.             if (!gHasQuickDraw3D)
  1620.                 break;
  1621.                 
  1622.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myXSize, &myYSize, &myZSize, &myOptions);
  1623.             VR3DObjects_EnlistBox(theWindowObject, myEntryID, myX, myY, myZ, myXSize, myYSize, myZSize, myOptions);
  1624.             break;
  1625.         }
  1626.  
  1627.         case kCreateCone: {                 // create a cone
  1628.             float        myX, myY, myZ;
  1629.             float        myMajRad, myMinRad, myHeight;
  1630.  
  1631.             if (!gHasQuickDraw3D15)
  1632.                 break;
  1633.                 
  1634.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1635.             VR3DObjects_EnlistCone(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1636.             break;
  1637.         }
  1638.  
  1639.         case kCreateCylinder: {             // create a cylinder
  1640.             float        myX, myY, myZ;
  1641.             float        myMajRad, myMinRad, myHeight;
  1642.  
  1643.             if (!gHasQuickDraw3D15)
  1644.                 break;
  1645.                 
  1646.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1647.             VR3DObjects_EnlistCylinder(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1648.             break;
  1649.         }
  1650.  
  1651.         case kCreateEllipsoid: {         // create an ellipsoid
  1652.             float        myX, myY, myZ;
  1653.             float        myMajRad, myMinRad, myHeight;
  1654.  
  1655.             if (!gHasQuickDraw3D15)
  1656.                 break;
  1657.                 
  1658.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1659.             VR3DObjects_EnlistEllipsoid(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1660.             break;
  1661.         }
  1662.  
  1663.         case kCreateTorus: {             // create a torus
  1664.             float        myX, myY, myZ;
  1665.             float        myMajRad, myMinRad, myHeight, myRatio;
  1666.  
  1667.             if (!gHasQuickDraw3D15)
  1668.                 break;
  1669.                 
  1670.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myRatio, &myOptions);
  1671.             VR3DObjects_EnlistTorus(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myRatio, myOptions);
  1672.             break;
  1673.         }
  1674.  
  1675.         case kCreateRectangle: {         // create a rectangle
  1676.             float        myX, myY, myZ;
  1677.             float        myX1, myY1, myZ1, myX2, myY2, myZ2, myX3, myY3, myZ3, myX4, myY4, myZ4;
  1678.  
  1679.             if (!gHasQuickDraw3D15)
  1680.                 break;
  1681.                 
  1682.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myX1, &myY1, &myZ1, &myX2, &myY2, &myZ2, &myX3, &myY3, &myZ3, &myX4, &myY4, &myZ4, &myOptions);
  1683.             VR3DObjects_EnlistRectangle(theWindowObject, myEntryID, myX, myY, myZ, myX1, myY1, myZ1, myX2, myY2, myZ2, myX3, myY3, myZ3, myX4, myY4, myZ4, myOptions);
  1684.             break;
  1685.         }
  1686.  
  1687.         case kOpen3DMFFile: {             // load a 3D object contained in a 3DMF file
  1688.             float        myX, myY, myZ;
  1689.  
  1690.             if (!gHasQuickDraw3D)
  1691.                 break;
  1692.                 
  1693.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld %s", &myEntryID, &myX, &myY, &myZ, &myOptions, myPathName);
  1694.             VR3DObjects_Enlist3DMFFile(theWindowObject, myEntryID, myX, myY, myZ, myOptions, myPathName);
  1695.             break;
  1696.         }
  1697.  
  1698.         case kSet3DObjLocation: {        // set the location of a 3D object
  1699.             float        myX, myY, myZ;
  1700.  
  1701.             if (theWindowObject == NULL)
  1702.                 break;
  1703.                 
  1704.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1705.             VR3DObjects_SetLocation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1706.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1707.             break;
  1708.         }
  1709.         
  1710.         case kSet3DObjColor: {            // set the color of a 3D object
  1711.             float        myRed, myGreen, myBlue;
  1712.  
  1713.             if (theWindowObject == NULL)
  1714.                 break;
  1715.                 
  1716.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myRed, &myGreen, &myBlue, &myOptions);
  1717.             VR3DObjects_SetColor(theWindowObject, myEntryID, myRed, myGreen, myBlue, myOptions);
  1718.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1719.             break;
  1720.         }
  1721.         
  1722.         case kSet3DObjTransp: {            // set the transparency level of a 3D object
  1723.             float        myRed, myGreen, myBlue;
  1724.  
  1725.             if (theWindowObject == NULL)
  1726.                 break;
  1727.                 
  1728.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myRed, &myGreen, &myBlue, &myOptions);
  1729.             VR3DObjects_SetTransparency(theWindowObject, myEntryID, myRed, myGreen, myBlue, myOptions);
  1730.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1731.             break;
  1732.         }
  1733.         
  1734.         case kSet3DObjInterp:            // set the interpolation style of a 3D object
  1735.             if (theWindowObject == NULL)
  1736.                 break;
  1737.                 
  1738.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1739.             VR3DObjects_SetInterpolation(theWindowObject, myEntryID, myUInt32, myOptions);
  1740.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1741.             break;
  1742.         
  1743.         case kSet3DObjBackface:            // set the backfacing style of a 3D object
  1744.             if (theWindowObject == NULL)
  1745.                 break;
  1746.                 
  1747.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1748.             VR3DObjects_SetBackfacing(theWindowObject, myEntryID, myUInt32, myOptions);
  1749.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1750.             break;
  1751.         
  1752.         case kSet3DObjFill:                // set the fill style of a 3D object
  1753.             if (theWindowObject == NULL)
  1754.                 break;
  1755.  
  1756.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1757.             VR3DObjects_SetFill(theWindowObject, myEntryID, myUInt32, myOptions);
  1758.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1759.             break;
  1760.         
  1761.         case kSet3DObjRotation: {        // set the rotation factors of a 3D object
  1762.             float        myX, myY, myZ;
  1763.  
  1764.             if (theWindowObject == NULL)
  1765.                 break;
  1766.                 
  1767.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1768.             myX = QTVRUtils_DegreesToRadians(myX);
  1769.             myY = QTVRUtils_DegreesToRadians(myY);
  1770.             myZ = QTVRUtils_DegreesToRadians(myZ);
  1771.             VR3DObjects_SetRotation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1772.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1773.             break;
  1774.         }
  1775.         
  1776.         case kSet3DObjRotState:            // set the rotation state of a 3D object
  1777.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1778.             VR3DObjects_SetRotationState(theWindowObject, myEntryID, myUInt32, myOptions);
  1779.             break;
  1780.         
  1781.         case kSet3DObjVisState:            // set the visibility state of a 3D object
  1782.             if (theWindowObject == NULL)
  1783.                 break;
  1784.                 
  1785.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1786.             VR3DObjects_SetVisibleState(theWindowObject, myEntryID, myUInt32, myOptions);
  1787.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1788.             break;
  1789.         
  1790.         case kSet3DObjTexture:            // set the texture of a 3D object
  1791.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myEntryID, &myUInt32, &myOptions, myPathName);
  1792.             VR3DObjects_SetTexture(theWindowObject, myEntryID, (Boolean)myUInt32, myOptions, myPathName);
  1793.             break;
  1794.         
  1795.         case kDestroy3DObject: {        // destroy a 3D object; note that the options are not yet defined
  1796.             VRScriptGenericPtr     myPointer;
  1797.  
  1798.             sscanf(theCommandLine, "%*s %ld %ld", &myEntryID, &myOptions);
  1799.             myPointer = VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QD3DObject, myEntryID);
  1800.             if (myPointer != NULL)
  1801.                 VRScript_DelistEntry(theWindowObject, myPointer);
  1802.             break;
  1803.         }
  1804. #endif // QD3D_AVAIL
  1805.         
  1806.         case kSet3DSndLocation: {        // set the location of a localized sound
  1807.             float        myX, myY, myZ;
  1808.  
  1809.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1810.             VRSound_SetLocation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1811.             VRSound_Update3DSoundEnv(theWindowObject);
  1812.             break;
  1813.         }
  1814.  
  1815.         case kSetVariable: {            // set the value of a variable; variables are used only in If commands
  1816.             char                    myVarName[kMaxVarNameLength];
  1817.             SInt32                    myVarValue;
  1818.             VRScriptVariablePtr        myPointer;
  1819.             
  1820.             sscanf(theCommandLine, "%*s %s %ld %ld", myVarName, &myVarValue, &myOptions);
  1821.             myPointer = VRScript_GetVariableEntry(theWindowObject, myVarName);
  1822.             
  1823.             if (myPointer == NULL) {
  1824.                 VRScript_EnlistVariable(theWindowObject, myVarName, myVarValue);
  1825.             } else {
  1826.                 if (myOptions == kVRValue_Absolute)
  1827.                     myPointer->fValue = myVarValue;
  1828.                 if (myOptions == kVRValue_Relative)
  1829.                     myPointer->fValue += myVarValue;
  1830.             }
  1831.             
  1832.             break;
  1833.         }
  1834.  
  1835.         case kIf: {                        // evaluate the expression "var op value"; execute a command if true
  1836.             char                    myVarName[kMaxVarNameLength];
  1837.             char                    myOperation[kMaxVarOpLength];
  1838.             SInt32                    myVarValue;
  1839.             VRScriptVariablePtr        myPointer;
  1840.             
  1841.             sscanf(theCommandLine, "%*s %s %s %ld %ld %s", myVarName, myOperation, &myVarValue, &myOptions, myCmdLine);
  1842.             myPointer = VRScript_GetVariableEntry(theWindowObject, myVarName);
  1843.             
  1844.             if (myPointer != NULL) {
  1845.                 Boolean                myRunCommand = false;
  1846.  
  1847.                 // find the appropriate operation and test for its satisfaction
  1848.                 if ((strcmp(myOperation, "=") == 0) || (strcmp(myOperation, "==") == 0))
  1849.                     myRunCommand = (myPointer->fValue == myVarValue);
  1850.                 else if (strcmp(myOperation, "!=") == 0)
  1851.                     myRunCommand = (myPointer->fValue != myVarValue);
  1852.                 else if (strcmp(myOperation, "<") == 0)
  1853.                     myRunCommand = (myPointer->fValue < myVarValue);
  1854.                 else if (strcmp(myOperation, "<=") == 0)
  1855.                     myRunCommand = (myPointer->fValue <= myVarValue);
  1856.                 else if (strcmp(myOperation, ">") == 0)
  1857.                     myRunCommand = (myPointer->fValue > myVarValue);
  1858.                 else if (strcmp(myOperation, ">=") == 0)
  1859.                     myRunCommand = (myPointer->fValue >= myVarValue);        
  1860.                     
  1861.                 if (myRunCommand) {
  1862.                     VRScript_UnpackString(myCmdLine);
  1863.                     VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine);
  1864.                 }
  1865.             }
  1866.             
  1867.             break;
  1868.         }
  1869.  
  1870.         case kSetSpriteVisState:        // set the visibility of a sprite on or off
  1871.             if (theWindowObject == NULL)
  1872.                 break;
  1873.                 
  1874.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1875.             VRSprites_SetVisibleState(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1876.             break;
  1877.  
  1878.         case kSetSpriteLayer:            // set the layer of a sprite
  1879.             if (theWindowObject == NULL)
  1880.                 break;
  1881.                 
  1882.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1883.             VRSprites_SetLayer(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1884.             break;
  1885.  
  1886.         case kSetSpriteGraphicsMode:    // set the graphics mode of a sprite
  1887.             if (theWindowObject == NULL)
  1888.                 break;
  1889.                 
  1890.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1891.             VRSprites_SetGraphicsMode(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1892.             break;
  1893.  
  1894.         case kSetSpriteImageIndex:        // set the image index of a sprite
  1895.             if (theWindowObject == NULL)
  1896.                 break;
  1897.                 
  1898.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1899.             VRSprites_SetImageIndex(theWindowObject, (QTAtomID)mySpriteID, (short)myUInt32, myOptions);
  1900.             break;
  1901.  
  1902.         case kSetSpriteMatrix: {        // set the matrix of a sprite
  1903.             float            myR0C0, myR0C1, myR0C2, myR1C0, myR1C1, myR1C2, myR2C0, myR2C1, myR2C2;
  1904.             MatrixRecord    myMatrix;
  1905.  
  1906.             if (theWindowObject == NULL)
  1907.                 break;
  1908.                 
  1909.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %f %f %ld", &mySpriteID, &myR0C0, &myR0C1, &myR0C2, &myR1C0, &myR1C1, &myR1C2, &myR2C0, &myR2C1, &myR2C2, &myOptions);
  1910.             myMatrix.matrix[0][0] = FloatToFixed(myR0C0);
  1911.             myMatrix.matrix[0][1] = FloatToFixed(myR0C1);
  1912.             myMatrix.matrix[0][2] = FloatToFract(myR0C2);
  1913.             myMatrix.matrix[1][0] = FloatToFixed(myR1C0);
  1914.             myMatrix.matrix[1][1] = FloatToFixed(myR1C1);
  1915.             myMatrix.matrix[1][2] = FloatToFract(myR1C2);
  1916.             myMatrix.matrix[2][0] = FloatToFixed(myR2C0);
  1917.             myMatrix.matrix[2][1] = FloatToFixed(myR2C1);
  1918.             myMatrix.matrix[2][2] = FloatToFract(myR2C2);
  1919.             VRSprites_SetMatrix(theWindowObject, (QTAtomID)mySpriteID, &myMatrix, myOptions);
  1920.             break;
  1921.         }
  1922.         
  1923.         case kSetSpriteLocation: {        // set the location of a sprite;
  1924.                                         // the h and v values are pixels relative to the sprite track's origin
  1925.             UInt32            myH, myV;
  1926.             Point            myPoint;
  1927.  
  1928.             if (theWindowObject == NULL)
  1929.                 break;
  1930.                 
  1931.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &mySpriteID, &myH, &myV, &myOptions);
  1932.             myPoint.h = (short)myH;
  1933.             myPoint.v = (short)myV;
  1934.             VRSprites_SetLocation(theWindowObject, (QTAtomID)mySpriteID, &myPoint, myOptions);
  1935.             break;
  1936.         }
  1937.  
  1938.         case kSetTrackVolume:             // set the volume of a sound track in an embedded QuickTime movie
  1939.         case kSetTrackState:             // enable or disable a track in an embedded QuickTime movie
  1940.         case kSetTrackLayer: {             // set the layer of a track in an embedded QuickTime movie
  1941.             UInt32                myValue;
  1942.             UInt32                myIndex;
  1943.             VRScriptMoviePtr    myMoviePtr = NULL;
  1944.             Track                myTrack = NULL;
  1945.  
  1946.             if (theWindowObject == NULL)
  1947.                 break;
  1948.             
  1949.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myEntryID, &myValue, &myIndex, &myOptions);
  1950.  
  1951.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1952.             if (myMoviePtr != NULL) {
  1953.                 if (myMoviePtr->fMovie != NULL)
  1954.                     myTrack = GetMovieIndTrack(myMoviePtr->fMovie, myIndex);
  1955.                     
  1956.                 if (myTrack == NULL)
  1957.                      break;
  1958.                 
  1959.                 switch (myCode) {
  1960.                     case kSetTrackVolume:
  1961.                         if (myOptions == kVRValue_Absolute)
  1962.                             SetTrackVolume(myTrack, (short)myValue);
  1963.                         else
  1964.                             SetTrackVolume(myTrack, (short)myValue + GetTrackVolume(myTrack));
  1965.                         break;
  1966.                     
  1967.                     case kSetTrackState:
  1968.                         if (myValue == kVRState_Toggle)
  1969.                             myValue = (UInt32)!GetTrackEnabled(myTrack);
  1970.             
  1971.                         SetTrackEnabled(myTrack, (Boolean)myValue);
  1972.                         break;
  1973.                     
  1974.                     case kSetTrackLayer:
  1975.                         SetTrackLayer(myTrack, (short)myValue);
  1976.                         break;
  1977.                 }     
  1978.             }
  1979.             
  1980.             break;
  1981.         }
  1982.                 
  1983.         case kSetMovieTime:              // set the current time of the specified movie
  1984.         case kSetMovieRate:              // set the rate of the specified movie
  1985.         case kSetMovieTimeScale: {         // set the time scale of the specified movie
  1986.             VRScriptMoviePtr    myMoviePtr = NULL;
  1987.  
  1988.             if (theWindowObject == NULL)
  1989.                 break;
  1990.             
  1991.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1992.  
  1993.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1994.             if (myMoviePtr != NULL)
  1995.                 if (myMoviePtr->fMovie != NULL)
  1996.                     switch (myCode) {
  1997.                         case kSetMovieTime:
  1998.                             SetMovieTimeValue(myMoviePtr->fMovie, (TimeValue)myUInt32);
  1999.                             break;
  2000.                         case kSetMovieRate:
  2001.                             SetMovieRate(myMoviePtr->fMovie, (Fixed)myUInt32);
  2002.                             break;
  2003.                         case kSetMovieTimeScale:
  2004.                             SetMovieTimeScale(myMoviePtr->fMovie, (TimeScale)myUInt32);
  2005.                             break;
  2006.                     }
  2007.             
  2008.             break;
  2009.         }
  2010.     
  2011.         case kInvalidCommand:
  2012.         default:
  2013.             // if we got here, we encountered an unrecognized command;
  2014.             // in verbose mode, print a warning
  2015.             if (gIsVerbose)
  2016.                 VRScript_PrintToDebugWindow(kUnknownCommandString);
  2017.             break;
  2018.             
  2019.     } // switch (myCode)
  2020.     
  2021. }
  2022.  
  2023.  
  2024. //////////
  2025. //
  2026. // VRScript_OpenDebugWindow
  2027. // Open the debug window.
  2028. //
  2029. //////////
  2030.  
  2031. WindowPtr VRScript_OpenDebugWindow (void)
  2032. {
  2033.     WindowPtr            myWindow = NULL;
  2034.     StringPtr            myTitle = QTUtils_ConvertCToPascalString(kDebugWindowTitle);
  2035. #if !USE_SIOUX_FOR_DEBUG
  2036.     Rect                myRect;
  2037.     GrafPtr                myPort = NULL;
  2038.         
  2039.     MacSetRect(&myRect, 50, 100, 700, 500);
  2040.     myWindow = NewCWindow(NULL, &myRect, myTitle, true, documentProc, (WindowPtr)-1, false, 0);
  2041.  
  2042.     if (myWindow != NULL) {
  2043.         GetPort(&myPort);
  2044.         MacSetPort(myWindow);
  2045.         TextSize(kDebugWindowTextSize);
  2046.         MacSetPort(myPort);
  2047.     }
  2048.  
  2049. #else
  2050.     // set up the SIOUX environment
  2051.     SIOUXSettings.initializeTB = false;
  2052.     SIOUXSettings.setupmenus = false;
  2053.     SIOUXSettings.standalone = false;
  2054.     SIOUXSettings.autocloseonquit = true;
  2055.     SIOUXSettings.asktosaveonclose = false;
  2056.     SIOUXSettings.showstatusline = false;
  2057.     SIOUXSettings.columns = 100;
  2058.     SIOUXSettings.rows = 20;
  2059.     SIOUXSettings.tabspaces = 1; 
  2060.          
  2061.     // initialize the debugging output and set the window title
  2062.     fprintf(stderr, "Beginning verbose state\n");
  2063.     SIOUXSetTitle(myTitle);
  2064.     myWindow = (WindowPtr)0x00000001;
  2065. #endif
  2066.     free(myTitle);
  2067.     return(myWindow);
  2068. }
  2069.  
  2070.  
  2071. //////////
  2072. //
  2073. // VRScript_PrintToDebugWindow
  2074. // Display the specified string in the debug window.
  2075. //
  2076. //////////
  2077.  
  2078. void VRScript_PrintToDebugWindow (char *theString)
  2079. {
  2080. #if USE_SIOUX_FOR_DEBUG
  2081.     fprintf(stderr, "%s\n", theString);
  2082. #else
  2083.     static short    myCurYPos = 0;
  2084.     GrafPtr            myPort;
  2085.     RgnHandle        myRegion;
  2086.     StringPtr        myString = QTUtils_ConvertCToPascalString(theString);
  2087.  
  2088.     if (gDebugWindow == NULL)
  2089.         return;
  2090.         
  2091.     GetPort(&myPort);
  2092.     MacSetPort(gDebugWindow);
  2093.     
  2094.     MoveTo(0, myCurYPos);
  2095.     DrawString(myString);
  2096.     
  2097.     if (myCurYPos >= (gDebugWindow->portRect.bottom - kDebugWindowLineSize)) {
  2098.         myRegion = NewRgn();
  2099.         ScrollRect(&gDebugWindow->portRect, 0, -kDebugWindowLineSize, myRegion);
  2100.         DisposeRgn(myRegion);
  2101.     } else {
  2102.         myCurYPos += kDebugWindowLineSize;
  2103.     }
  2104.     
  2105.     MacSetPort(myPort);
  2106.     free(myString);
  2107. #endif
  2108. }
  2109.  
  2110.  
  2111. //////////
  2112. //
  2113. // VRScript_SetCurrentDirectory
  2114. // Set the current (or default) directory. All filenames specified in the script file that are not full
  2115. // pathnames are taken as relative to this directory.
  2116. //
  2117. // A bit of terminology: on MacOS, the directory that is searched when only a filename is given is called
  2118. // the "default directory"; on Windows, this is called the "current directory".
  2119. //
  2120. // NOTE: The theFSSpecPtr parameter must specify *a file* in the directory to be made current. That file
  2121. // does not need to exist, however.
  2122. //
  2123. //////////
  2124.  
  2125. void VRScript_SetCurrentDirectory (FSSpecPtr theFSSpecPtr)
  2126. {
  2127. #if TARGET_OS_MAC
  2128.     HSetVol(NULL, theFSSpecPtr->vRefNum, theFSSpecPtr->parID);
  2129. #elif TARGET_OS_WIN32
  2130.     char         myFilePath[MAX_PATH];
  2131.  
  2132.     myFilePath[0] = '\0';
  2133.     FSSpecToNativePathName(theFSSpecPtr, myFilePath, MAX_PATH, kDirectoryPathOnly);
  2134.     SetCurrentDirectory(myFilePath);
  2135. #endif
  2136. }
  2137.  
  2138.  
  2139. //////////
  2140. //
  2141. // VRScript_SetCurrentMovie
  2142. // Set the QuickTime movie currently displayed in the window attached to theWindowObject.
  2143. //
  2144. //////////
  2145.  
  2146. void VRScript_SetCurrentMovie (WindowObject theWindowObject, UInt32 theOverlayType, UInt32 theNameType, UInt32 theOptions, char *thePathName)
  2147. {
  2148. #pragma unused(theOverlayType, theOptions)
  2149.     FSSpec                myFSSpec;
  2150.     Movie                myMovie = NULL;
  2151.     MovieController        myMC = NULL;
  2152.     short                myRefNum = 0;
  2153.     Movie                myPrevMovie = NULL;
  2154.     MovieController        myPrevMC = NULL;
  2155.     short                myPrevRefNum = 0;
  2156.     short                myResID = 0;
  2157.     WindowReference        myWindow = NULL;
  2158.     QTVRInstance        myInstance = NULL;
  2159. #if TARGET_OS_WIN32
  2160.     char                 myFileName[MAX_PATH];
  2161. #endif
  2162.     OSErr                myErr = noErr;
  2163.  
  2164.     // make sure we have a valid window object and movie window
  2165.     if (theWindowObject == NULL)
  2166.         return;
  2167.  
  2168.     myWindow = (**theWindowObject).fWindow;
  2169.     if (myWindow == NULL)
  2170.         return;
  2171.     
  2172.     // get the previous movie and controller
  2173.     myPrevMovie = (**theWindowObject).fMovie;
  2174.     myPrevMC = (**theWindowObject).fController;
  2175.     myPrevRefNum = (**theWindowObject).fFileRefNum;
  2176.     
  2177.     // find the target QuickTime movie file
  2178.     switch (theNameType) {
  2179.         case kVRRelativePath:
  2180.         case kVRAbsolutePath:
  2181.             myErr = FileUtils_MakeFSSpecForPathName(0, 0, thePathName, &myFSSpec);
  2182.             if (myErr != noErr)
  2183.                 goto bail;
  2184.                 
  2185.             // open the specified movie file;
  2186.             // ideally, we'd like read and write permission, but we'll settle for read-only permission
  2187.             myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdWrPerm);
  2188.             if (myErr != noErr)
  2189.                 myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdPerm);
  2190.  
  2191.             // if we couldn't open the file with even just read-only permission, bail....
  2192.             if (myErr != noErr)
  2193.                 goto bail;
  2194.  
  2195.             // now fetch the first movie from the file
  2196.             myResID = 0;
  2197.             myErr = NewMovieFromFile(&myMovie, myRefNum, &myResID, NULL, newMovieActive, NULL);
  2198.             if (myErr != noErr)
  2199.                 goto bail;
  2200.             
  2201.             CloseMovieFile(myRefNum);
  2202.             break;
  2203.             
  2204.         case kVRAbsoluteURL: {
  2205.             char     *myString;
  2206.             
  2207.             myResID = 0;
  2208.             myMovie = URLUtils_NewMovieFromURL(thePathName, newMovieActive, &myResID);
  2209.             
  2210.             myString = URLUtils_GetURLBasename(thePathName);
  2211.             FileUtils_MakeFSSpecForPathName(0, 0, myString, &myFSSpec);
  2212.             free(myString);
  2213.             
  2214.             break;
  2215.         }
  2216.             
  2217.         case kVRRelativeURL:
  2218.             // to be supplied
  2219.             break;
  2220.             
  2221.         default:
  2222.             goto bail;    // unknown pathname type
  2223.     }
  2224.     
  2225.     // make sure the movie uses the window GWorld in all situations
  2226.     SetMovieGWorld(myMovie, (CGrafPtr)GetPortFromWindowReference(myWindow), GetGWorldDevice((CGrafPtr)GetPortFromWindowReference(myWindow)));
  2227.  
  2228.     // create and configure the movie controller
  2229.     myMC = SetupMovieWindowWithController(myMovie, myWindow, false);
  2230.     if (myMC == NULL)
  2231.         goto bail;
  2232.         
  2233.     //////////
  2234.     //
  2235.     // in with the new....
  2236.     //
  2237.     //////////
  2238.     
  2239.     // set the window title
  2240. #if TARGET_OS_MAC
  2241.     SetWTitle(myWindow, myFSSpec.name);
  2242. #elif TARGET_OS_WIN32
  2243.     FSSpecToNativePathName(&myFSSpec, myFileName, MAX_PATH, kFileNameOnly);
  2244.     SetWindowText(myWindow, myFileName);
  2245. #endif
  2246.  
  2247.     // get the QTVR instance
  2248.     QTVRGetQTVRInstance(&myInstance, QTVRGetQTVRTrack(myMovie, 1), myMC);
  2249.     
  2250.     // store movie info in the window record
  2251.     (**theWindowObject).fMovie = myMovie;
  2252.     (**theWindowObject).fController = myMC;
  2253.     (**theWindowObject).fFileResID = myResID;
  2254.     (**theWindowObject).fFileRefNum = myRefNum;
  2255.     (**theWindowObject).fCanResizeWindow = true;
  2256.     (**theWindowObject).fDirty = false;
  2257.     (**theWindowObject).fInstance = myInstance;
  2258.     (**theWindowObject).fFileFSSpec = myFSSpec;
  2259.  
  2260.     // redraw the window
  2261.     MCInvalidate(myMC, (GrafPtr)GetPortFromWindowReference(myWindow), MCGetWindowRgn(myMC, (GrafPtr)GetPortFromWindowReference(myWindow)));
  2262.  
  2263.     // reset the cursor
  2264.     InitCursor();
  2265.     
  2266.     //////////
  2267.     //
  2268.     // out with the old....
  2269.     //
  2270.     //////////
  2271.     
  2272.     // we'd like to be able to just call DisposeMovieController and DisposeMovie on the
  2273.     // previous controller and movie, but we can't; the reason is that this function might
  2274.     // have been called in response to a user event (such as a click on a hot spot) that
  2275.     // was passed to MCIsPlayerEvent in our main event loop. Experience tells me that it's
  2276.     // not good to dispose of the movie controller inside code called by MCIsPlayerEvent.
  2277.     // Our solution is to defer disposal until a safe time.
  2278.     
  2279.     gPreviousMC = myPrevMC;
  2280.     gPreviousMovie = myPrevMovie;
  2281.         
  2282.     if (myPrevRefNum != 0)
  2283.         CloseMovieFile(myPrevRefNum);
  2284.  
  2285.     VRMoov_StartMovie(myMovie);
  2286.         
  2287.     return;
  2288.     
  2289. bail:
  2290.     // if we arrived here, an error occurred and we could not load the new movie;
  2291.     // undo any work we did to install the new movie
  2292.     if (myMC != NULL)
  2293.         DisposeMovieController(myMC);
  2294.         
  2295.     if (myMovie != NULL)
  2296.         DisposeMovie(myMovie);
  2297.         
  2298.     if (myRefNum != 0)
  2299.         CloseMovieFile(myRefNum);
  2300. }
  2301.  
  2302.  
  2303. //////////
  2304. //
  2305. // VRScript_SetControllerBarState
  2306. // Set the state of the controller bar.
  2307. //
  2308. //////////
  2309.  
  2310. void VRScript_SetControllerBarState (WindowObject theWindowObject, Boolean theState, UInt32 theOptions)
  2311. {
  2312. #pragma unused(theOptions)
  2313.  
  2314.     if (theWindowObject == NULL)
  2315.         return;
  2316.  
  2317.     if (theState == kVRState_Toggle)
  2318.         theState = !MCGetVisible((**theWindowObject).fController);
  2319.     
  2320.     MCSetVisible((**theWindowObject).fController, theState);
  2321. }
  2322.  
  2323.  
  2324. //////////
  2325. //
  2326. // VRScript_SetControllerButtonState
  2327. // Set the state of the specified button (or text display) in the controller bar.
  2328. //
  2329. //////////
  2330.  
  2331. void VRScript_SetControllerButtonState (WindowObject theWindowObject, UInt32 theButton, Boolean theState, UInt32 theOptions)
  2332. {
  2333. #pragma unused(theOptions)
  2334.     
  2335.     long    myButton;
  2336.     
  2337.     if (theWindowObject == NULL)
  2338.         return;
  2339.         
  2340.     if ((**theWindowObject).fController == NULL)
  2341.         return;
  2342.  
  2343.     // convert VRScript's enum into the actual value expected by the movie controller
  2344.     switch (theButton) {
  2345.         case kVRButton_Step:            myButton = mcFlagSuppressStepButtons;            break;
  2346.         case kVRButton_Speaker:            myButton = mcFlagSuppressSpeakerButton;            break;
  2347.         case kVRButton_GoBack:            myButton = mcFlagQTVRSuppressBackBtn;            break;
  2348.         case kVRButton_ZoomInOut:        myButton = mcFlagQTVRSuppressZoomBtns;            break;
  2349.         case kVRButton_ShowHotSpots:    myButton = mcFlagQTVRSuppressHotSpotBtn;        break;
  2350.         case kVRButton_Translate:        myButton = mcFlagQTVRSuppressTranslateBtn;        break;
  2351.         case kVRButton_HelpText:        myButton = mcFlagQTVRSuppressHelpText;            break;
  2352.         case kVRButton_HotSpotNames:    myButton = mcFlagQTVRSuppressHotSpotNames;        break;
  2353.         case kVRButton_Custom:            myButton = mcFlagsUseCustomButton;                break;
  2354.         default:
  2355.             break;
  2356.     }
  2357.  
  2358.     // set the correct state of the button        
  2359.     switch (theState) {
  2360.         case kVRState_Hide:
  2361.             QTUtils_HideControllerButton((**theWindowObject).fController, myButton);
  2362.             break;
  2363.         case kVRState_Show:
  2364.             QTUtils_ShowControllerButton((**theWindowObject).fController, myButton);
  2365.             break;
  2366.         case kVRState_Toggle:
  2367.             QTUtils_ToggleControllerButton((**theWindowObject).fController, myButton);
  2368.             break;
  2369.         default:
  2370.             break;
  2371.     }
  2372. }
  2373.  
  2374.  
  2375. //////////
  2376. //
  2377. // VRScript_SetResizeState
  2378. // Set the state of window resizing.
  2379. //
  2380. //////////
  2381.  
  2382. void VRScript_SetResizeState (WindowObject theWindowObject, Boolean theState, UInt32 theOptions)
  2383. {
  2384. #pragma unused(theOptions)
  2385.  
  2386.     Rect            myRect;
  2387.  
  2388.     if (theWindowObject == NULL)
  2389.         return;
  2390.  
  2391.     if (theState == kVRState_Toggle)
  2392.         theState = !(**theWindowObject).fCanResizeWindow;
  2393.  
  2394.     (**theWindowObject).fCanResizeWindow = theState;
  2395.     
  2396.     // set size of growable window
  2397.     if ((**theWindowObject).fCanResizeWindow)
  2398.         MacSetRect(&myRect, gLimitRect.left, gLimitRect.top, gLimitRect.right, gLimitRect.bottom);
  2399.     else
  2400.         MacSetRect(&myRect, 0, 0, 0, 0);
  2401.     
  2402.     MCDoAction((**theWindowObject).fController, mcActionSetGrowBoxBounds, &myRect);
  2403.     QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  2404. }
  2405.  
  2406.  
  2407. //////////
  2408. //
  2409. // VRScript_SetAngleConstraints
  2410. // Set the pan, tilt, or zoom constraints.
  2411. // Note: this function expects theMinAngle and theMaxAngle to be in *degrees*.
  2412. //
  2413. //////////
  2414.  
  2415. void VRScript_SetAngleConstraints (WindowObject theWindowObject, UInt16 theKind, float theMinAngle, float theMaxAngle, UInt32 theOptions)
  2416. {
  2417.     float    myMinAngle;
  2418.     float    myMaxAngle;
  2419.  
  2420.     if (theWindowObject == NULL)
  2421.         return;
  2422.     
  2423.     myMinAngle = QTVRUtils_DegreesToRadians(theMinAngle);
  2424.     myMaxAngle = QTVRUtils_DegreesToRadians(theMaxAngle);
  2425.     
  2426.     if (theOptions == kVRValue_Relative) {
  2427.         float    myCurrMin;
  2428.         float    myCurrMax;
  2429.         OSErr    myErr;
  2430.  
  2431.         myErr = QTVRGetConstraints((**theWindowObject).fInstance, theKind, &myCurrMin, &myCurrMax);
  2432.         if (myErr == noErr) {
  2433.             myMinAngle += myCurrMin;
  2434.             myMaxAngle += myCurrMax;
  2435.         }
  2436.     }
  2437.                 
  2438.     QTVRSetConstraints((**theWindowObject).fInstance, theKind, myMinAngle, myMaxAngle);
  2439.     QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  2440. }
  2441.  
  2442.  
  2443. //////////
  2444. //
  2445. // VRScript_OpenResourceFile
  2446. // Open the specified resource file and add it to the application's resource chain.
  2447. // Returns the file reference number, if successful, or -1 otherwise.
  2448. //
  2449. //////////
  2450.  
  2451. short VRScript_OpenResourceFile (WindowObject theWindowObject, UInt32 theOptions, char *thePathName)
  2452. {
  2453. #pragma unused(theWindowObject, theOptions)
  2454.  
  2455.     FSSpec        myFSSpec;
  2456.     short        myRefNum = -1;
  2457.  
  2458.     // we accept either full pathnames or partial pathnames specified relative to the default directory
  2459.     // on the default volume
  2460.     FileUtils_MakeFSSpecForPathName(0, 0L, thePathName, &myFSSpec);
  2461.  
  2462.     myRefNum = FSpOpenResFile(&myFSSpec, fsRdPerm);
  2463.     if (myRefNum == -1)
  2464.         ;                    // no error handling yet....
  2465.         
  2466.     return(myRefNum);
  2467. }
  2468.  
  2469.  
  2470. //////////
  2471. //
  2472. // VRScript_EnlistSound
  2473. // Install an ambient sound.
  2474. //
  2475. //////////
  2476.  
  2477. VRScriptSoundPtr VRScript_EnlistSound (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theResID, UInt32 theEntryID, UInt32 theMode, UInt32 theFade, UInt32 theOptions, SndChannelPtr theChannel, SndListHandle theResource)
  2478. {
  2479.     VRScriptSoundPtr        myPointer;
  2480.     ApplicationDataHdl        myAppData;
  2481.     
  2482.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2483.     if (myAppData == NULL)
  2484.         return(NULL);
  2485.     
  2486.     myPointer = (VRScriptSoundPtr)NewPtrClear(sizeof(VRScriptSound));
  2487.     if (myPointer != NULL) {
  2488.         myPointer->fEntryType = kVREntry_Sound;
  2489.         myPointer->fEntryID = theEntryID;
  2490.         myPointer->fNodeID = theNodeID;
  2491.         myPointer->fOptions = theOptions;
  2492.         myPointer->fMode = theMode;
  2493.         myPointer->fSoundContainer = kVRSound_SoundResource;
  2494.         myPointer->fResID = theResID;
  2495.         myPointer->fResourceData = theResource;
  2496.         myPointer->fChannel = theChannel;
  2497.         myPointer->fFadeWhenStopping = (Boolean)theFade;
  2498.         myPointer->fSoundIsLocalized = false;
  2499.         myPointer->fSource = 0;
  2500.         myPointer->fLocation.x = 0.0;
  2501.         myPointer->fLocation.y = 0.0;
  2502.         myPointer->fLocation.z = 0.0;
  2503.         myPointer->fProjAngle = 0.0;
  2504.         myPointer->fNextEntry = (VRScriptSoundPtr)(**myAppData).fListArray[kVREntry_Sound];
  2505.         (**myAppData).fListArray[kVREntry_Sound] = (VRScriptGenericPtr)myPointer;
  2506.     }
  2507.     
  2508.     return(myPointer);
  2509. }
  2510.  
  2511.  
  2512. //////////
  2513. //
  2514. // VRScript_EnlistLocalizedSound
  2515. // Install a localized sound.
  2516. //
  2517. //////////
  2518.  
  2519. VRScriptSoundPtr VRScript_EnlistLocalizedSound (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theResID, UInt32 theEntryID, float theX, float theY, float theZ, float theProjAngle, UInt32 theMode, UInt32 theFade, UInt32 theOptions, SndChannelPtr theChannel, SndListHandle theResource, SSpSourceReference theSource)
  2520. {
  2521.     VRScriptSoundPtr        myPointer;
  2522.     ApplicationDataHdl        myAppData;
  2523.     
  2524.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2525.     if (myAppData == NULL)
  2526.         return(NULL);
  2527.  
  2528.     myPointer = (VRScriptSoundPtr)NewPtrClear(sizeof(VRScriptSound));
  2529.     if (myPointer != NULL) {
  2530.         myPointer->fEntryType = kVREntry_Sound;
  2531.         myPointer->fEntryID = theEntryID;
  2532.         myPointer->fNodeID = theNodeID;
  2533.         myPointer->fOptions = theOptions;
  2534.         myPointer->fMode = theMode;
  2535.         myPointer->fSoundContainer = kVRSound_SoundResource;
  2536.         myPointer->fResID = theResID;
  2537.         myPointer->fResourceData = theResource;
  2538.         myPointer->fChannel = theChannel;
  2539.         myPointer->fSource = theSource;
  2540.         myPointer->fLocation.x = theX;
  2541.         myPointer->fLocation.y = theY;
  2542.         myPointer->fLocation.z = theZ;
  2543.         myPointer->fProjAngle = theProjAngle;
  2544.         myPointer->fFadeWhenStopping = (Boolean)theFade;
  2545.         myPointer->fSoundIsLocalized = true;
  2546.         myPointer->fNextEntry = (VRScriptSoundPtr)(**myAppData).fListArray[kVREntry_Sound];
  2547.         (**myAppData).fListArray[kVREntry_Sound] = (VRScriptGenericPtr)myPointer;
  2548.     }
  2549.     
  2550.     return(myPointer);
  2551. }
  2552.  
  2553.  
  2554. //////////
  2555. //
  2556. // VRScript_EnlistMovie
  2557. // Install a QuickTime movie by adding the given information to our linked list.
  2558. //
  2559. //////////
  2560.  
  2561. VRScriptMoviePtr VRScript_EnlistMovie (
  2562.                 WindowObject theWindowObject,
  2563.                 UInt32 theNodeID,
  2564.                 UInt32 theEntryID,
  2565.                 float thePanAngle,
  2566.                 float theTiltAngle,
  2567.                 float theScale, 
  2568.                 float theWidth, 
  2569.                 UInt32 theKeyRed, 
  2570.                 UInt32 theKeyGreen, 
  2571.                 UInt32 theKeyBlue, 
  2572.                 Boolean theUseBuffer,
  2573.                 Boolean theUseCenter,
  2574.                 Boolean theUseKey,
  2575.                 Boolean theUseHide,
  2576.                 Boolean theUseDir,
  2577.                 Boolean theRotate,
  2578.                 float theVolAngle,
  2579.                 UInt32 theMode,
  2580.                 UInt32 theOptions,
  2581.                 char *thePathName)
  2582. {
  2583.     VRScriptMoviePtr        myPointer;
  2584.     ApplicationDataHdl        myAppData;
  2585.  
  2586.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2587.     if (myAppData == NULL)
  2588.         return(NULL);
  2589.  
  2590.     myPointer = (VRScriptMoviePtr)NewPtrClear(sizeof(VRScriptMovie));
  2591.     if (myPointer != NULL) {
  2592.         myPointer->fEntryType = kVREntry_QTMovie;
  2593.         myPointer->fEntryID = theEntryID;
  2594.         myPointer->fNodeID = theNodeID;
  2595.         myPointer->fOptions = theOptions;
  2596.         myPointer->fMode = theMode;
  2597.         myPointer->fMovie = NULL;
  2598.         myPointer->fOffscreenGWorld = NULL;
  2599.         myPointer->fOffscreenPixMap = NULL;
  2600.         myPointer->fPrevBBufGWorld = NULL;
  2601.         myPointer->fMovieCenter.x = thePanAngle;
  2602.         myPointer->fMovieCenter.y = theTiltAngle;
  2603.         myPointer->fMovieScale = theScale;
  2604.         myPointer->fMovieWidth = theWidth;
  2605.         myPointer->fUseOffscreenGWorld = theUseBuffer;
  2606.         myPointer->fUseMovieCenter = theUseCenter;
  2607.         myPointer->fQTMovieHasSound = false;        // we don't really know until we open the file....
  2608.         myPointer->fQTMovieHasVideo = false;        // we don't really know until we open the file....
  2609.         myPointer->fCompositeMovie = theUseKey;
  2610.         myPointer->fUseHideRegion = theUseHide;
  2611.         myPointer->fChromaColor.red = (unsigned short)theKeyRed;
  2612.         myPointer->fChromaColor.green = (unsigned short)theKeyGreen;
  2613.         myPointer->fChromaColor.blue = (unsigned short)theKeyBlue;
  2614.         myPointer->fHideRegion = NULL;
  2615.         myPointer->fImageDesc = NULL;
  2616.         myPointer->fImageSequence = 0;
  2617.         myPointer->fSoundIsLocalized = theUseDir;
  2618.         myPointer->fDoRotateMovie = theRotate;
  2619.         myPointer->fVolAngle = theVolAngle;
  2620.         myPointer->fMediaHandler = NULL;
  2621.         
  2622.         SetIdentityMatrix(&myPointer->fMovieMatrix);
  2623.         SetIdentityMatrix(&myPointer->fOrigMovieMatrix);
  2624.         
  2625.         myPointer->fPathname = malloc(strlen(thePathName) + 1);
  2626.         strncpy(myPointer->fPathname, thePathName, strlen(thePathName) + 1);
  2627.         myPointer->fNextEntry = (VRScriptMoviePtr)(**myAppData).fListArray[kVREntry_QTMovie];
  2628.         (**myAppData).fListArray[kVREntry_QTMovie] = (VRScriptGenericPtr)myPointer;
  2629.     }
  2630.     
  2631.     return(myPointer);
  2632. }
  2633.  
  2634.  
  2635. //////////
  2636. //
  2637. // VRScript_Enlist3DObject
  2638. // Install a 3D object.
  2639. //
  2640. //////////
  2641.  
  2642. #if QD3D_AVAIL
  2643. void VRScript_Enlist3DObject (WindowObject theWindowObject, TQ3GroupObject theGroup, UInt32 theEntryID, float theX, float theY, float theZ, UInt32 theOptions)
  2644. {
  2645.     VRScript3DObjPtr        myPointer;
  2646.     ApplicationDataHdl        myAppData;
  2647.     TQ3Point3D                myPoint;
  2648.     
  2649.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2650.     if (myAppData == NULL)
  2651.         return;
  2652.     
  2653.     myPointer = (VRScript3DObjPtr)NewPtrClear(sizeof(VRScript3DObj));
  2654.     if (myPointer != NULL) {
  2655.         myPointer->fEntryType = kVREntry_QD3DObject;
  2656.         myPointer->fEntryID = theEntryID;
  2657.         myPointer->fOptions = theOptions;
  2658.         myPointer->fModel = theGroup;
  2659.  
  2660.         myPointer->fInterpolation = Q3InterpolationStyle_New((TQ3InterpolationStyle)kDefaultInterpolation);
  2661.         myPointer->fBackFacing = Q3BackfacingStyle_New((TQ3BackfacingStyle)kDefaultBackfacing);
  2662.         myPointer->fFillStyle = Q3FillStyle_New((TQ3FillStyle)kDefaultFill);
  2663.         
  2664.         Q3Matrix4x4_SetIdentity(&(myPointer->fRotation));    
  2665.         myPointer->fRotateFactors.x = kDefaultRotateRadians;        // default rotation factors
  2666.         myPointer->fRotateFactors.y = kDefaultRotateRadians;
  2667.         myPointer->fRotateFactors.y = kDefaultRotateRadians;
  2668.             
  2669.         Q3Point3D_Set(&myPoint, -1.0 * theX, theY, -1.0 * theZ);
  2670.         myPointer->fGroupCenter = myPoint;
  2671.         myPointer->fGroupScale = kDefaultScale;
  2672.         myPointer->fTexture = NULL;
  2673.         myPointer->fTextureIsMovie = false;
  2674.         myPointer->fModelIsVisible = true;
  2675.         myPointer->fModelIsAnimated = false;
  2676.         myPointer->fNextEntry = (VRScript3DObjPtr)(**myAppData).fListArray[kVREntry_QD3DObject];
  2677.         (**myAppData).fListArray[kVREntry_QD3DObject] = (VRScriptGenericPtr)myPointer;
  2678.     }
  2679. }
  2680. #endif
  2681.  
  2682.  
  2683. //////////
  2684. //
  2685. // VRScript_EnlistOverlayPicture
  2686. // Install an overlay picture by adding the given information to our linked list.
  2687. //
  2688. //////////
  2689.  
  2690. VRScriptPicturePtr VRScript_EnlistOverlayPicture (WindowObject theWindowObject, UInt32 theResID, UInt32 theEntryID, UInt32 theHeight, UInt32 theWidth, UInt32 thePegSides, UInt32 theOffset, PicHandle theResource, UInt32 theOptions)
  2691. {
  2692.     VRScriptPicturePtr        myPointer;
  2693.     ApplicationDataHdl        myAppData;
  2694.  
  2695.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2696.     if (myAppData == NULL)
  2697.         return(NULL);
  2698.  
  2699.     myPointer = (VRScriptPicturePtr)NewPtrClear(sizeof(VRScriptPicture));
  2700.     if (myPointer != NULL) {
  2701.         myPointer->fEntryType = kVREntry_OverlayPicture;
  2702.         myPointer->fEntryID = theEntryID;
  2703.         myPointer->fNodeID = 0;
  2704.         myPointer->fOptions = theOptions;
  2705.         myPointer->fResID = theResID;
  2706.         myPointer->fBoxHeight = theHeight;
  2707.         myPointer->fBoxWidth = theWidth;
  2708.         myPointer->fPegSides = thePegSides;
  2709.         myPointer->fOffset = theOffset;
  2710.         myPointer->fResourceData = theResource;
  2711.         myPointer->fNextEntry = (VRScriptPicturePtr)(**myAppData).fListArray[kVREntry_OverlayPicture];
  2712.         (**myAppData).fListArray[kVREntry_OverlayPicture] = (VRScriptGenericPtr)myPointer;
  2713.     }
  2714.     
  2715.     return(myPointer);
  2716. }
  2717.  
  2718.  
  2719. //////////
  2720. //
  2721. // VRScript_EnlistTimedCommand
  2722. // Install a timed-activated command by adding the given information to our linked list.
  2723. //
  2724. //////////
  2725.  
  2726. void VRScript_EnlistTimedCommand (WindowObject theWindowObject, UInt32 theTicks, UInt32 theMode, UInt32 theNodeID, UInt32 theRepeat, UInt32 thePeriod, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2727. {
  2728.     VRScriptAtTimePtr        myPointer;
  2729.     ApplicationDataHdl        myAppData;
  2730.  
  2731.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2732.     if (myAppData == NULL)
  2733.         return;
  2734.  
  2735.     myPointer = (VRScriptAtTimePtr)NewPtrClear(sizeof(VRScriptAtTime));
  2736.     if (myPointer != NULL) {
  2737.         myPointer->fEntryType = kVREntry_TimedCommand;
  2738.         myPointer->fNodeID = theNodeID;
  2739.         myPointer->fOptions = theOptions;
  2740.         myPointer->fTime = theTicks;
  2741.         myPointer->fMode = theMode;
  2742.         myPointer->fTimeInstalled = gAbsoluteElapsedTime;
  2743.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2744.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2745.         myPointer->fRepeat = (Boolean)theRepeat;
  2746.         myPointer->fPeriod = thePeriod;
  2747.         myPointer->fMaxExecutions = theMaxTimes;
  2748.         myPointer->fNextEntry = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  2749.         (**myAppData).fListArray[kVREntry_TimedCommand] = (VRScriptGenericPtr)myPointer;
  2750.     }
  2751. }
  2752.  
  2753.  
  2754. //////////
  2755. //
  2756. // VRScript_EnlistQuitCommand
  2757. // Install an application-quit command by adding the given information to our linked list.
  2758. //
  2759. //////////
  2760.  
  2761. void VRScript_EnlistQuitCommand (WindowObject theWindowObject, UInt32 theOptions, char *theCmdLine)
  2762. {
  2763.     VRScriptAtQuitPtr        myPointer;
  2764.     ApplicationDataHdl        myAppData;
  2765.  
  2766.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2767.     if (myAppData == NULL)
  2768.         return;
  2769.  
  2770.     myPointer = (VRScriptAtQuitPtr)NewPtrClear(sizeof(VRScriptAtQuit));
  2771.     if (myPointer != NULL) {
  2772.         myPointer->fEntryType = kVREntry_QuitCommand;
  2773.         myPointer->fOptions = theOptions;
  2774.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2775.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2776.         myPointer->fNextEntry = (VRScriptAtQuitPtr)(**myAppData).fListArray[kVREntry_QuitCommand];
  2777.         (**myAppData).fListArray[kVREntry_QuitCommand] = (VRScriptGenericPtr)myPointer;
  2778.     }
  2779. }
  2780.  
  2781.  
  2782. //////////
  2783. //
  2784. // VRScript_EnlistMouseOverHSCommand
  2785. // Install a mouse-over hot spot command by adding the given information to our linked list.
  2786. //
  2787. //////////
  2788.  
  2789. void VRScript_EnlistMouseOverHSCommand (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theHotSpotID, OSType theHotSpotType, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2790. {
  2791.     VRScriptAtMOHSPtr        myPointer;
  2792.     ApplicationDataHdl        myAppData;
  2793.  
  2794.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2795.     if (myAppData == NULL)
  2796.         return;
  2797.  
  2798.     myPointer = (VRScriptAtMOHSPtr)NewPtrClear(sizeof(VRScriptAtMOHS));
  2799.     if (myPointer != NULL) {
  2800.         myPointer->fEntryType = kVREntry_MouseOverHS;
  2801.         myPointer->fNodeID = theNodeID;
  2802.         myPointer->fOptions = theOptions;                            // the hot spot action selector
  2803.         myPointer->fSelectByID = theHotSpotID > 0 ? true : false;
  2804.         myPointer->fHotSpotID = theHotSpotID;
  2805.         myPointer->fHotSpotType = theHotSpotType;
  2806.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2807.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2808.         myPointer->fMaxExecutions = theMaxTimes;
  2809.         myPointer->fNextEntry = (VRScriptAtMOHSPtr)(**myAppData).fListArray[kVREntry_MouseOverHS];
  2810.         (**myAppData).fListArray[kVREntry_MouseOverHS] = (VRScriptGenericPtr)myPointer;
  2811.     }
  2812. }
  2813.  
  2814.  
  2815. //////////
  2816. //
  2817. // VRScript_EnlistClickHSCommand
  2818. // Install a hot spot click command by adding the given information to our linked list.
  2819. //
  2820. //////////
  2821.  
  2822. void VRScript_EnlistClickHSCommand (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theHotSpotID, OSType theHotSpotType, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2823. {
  2824.     VRScriptClickHSPtr        myPointer;
  2825.     ApplicationDataHdl        myAppData;
  2826.  
  2827.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2828.     if (myAppData == NULL)
  2829.         return;
  2830.  
  2831.     myPointer = (VRScriptClickHSPtr)NewPtrClear(sizeof(VRScriptClickHS));
  2832.     if (myPointer != NULL) {
  2833.         myPointer->fEntryType = kVREntry_ClickHS;
  2834.         myPointer->fNodeID = theNodeID;
  2835.         myPointer->fOptions = theOptions;
  2836.         myPointer->fSelectByID = theHotSpotID > 0 ? true : false;
  2837.         myPointer->fHotSpotID = theHotSpotID;
  2838.         myPointer->fHotSpotType = theHotSpotType;
  2839.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2840.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2841.         myPointer->fMaxExecutions = theMaxTimes;
  2842.         myPointer->fNextEntry = (VRScriptClickHSPtr)(**myAppData).fListArray[kVREntry_ClickHS];
  2843.         (**myAppData).fListArray[kVREntry_ClickHS] = (VRScriptGenericPtr)myPointer;
  2844.     }
  2845. }
  2846.  
  2847.  
  2848. //////////
  2849. //
  2850. // VRScript_EnlistClickCustomButtonCommand
  2851. // Install a custom button click command by adding the given information to our linked list.
  2852. //
  2853. //////////
  2854.  
  2855. void VRScript_EnlistClickCustomButtonCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2856. {
  2857.     VRScriptClickCustomPtr    myPointer;
  2858.     ApplicationDataHdl        myAppData;
  2859.  
  2860.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2861.     if (myAppData == NULL)
  2862.         return;
  2863.  
  2864.     myPointer = (VRScriptClickCustomPtr)NewPtrClear(sizeof(VRScriptClickCustom));
  2865.     if (myPointer != NULL) {
  2866.         myPointer->fEntryType = kVREntry_ClickCustom;
  2867.         myPointer->fNodeID = theNodeID;
  2868.         myPointer->fOptions = theOptions;
  2869.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2870.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2871.         myPointer->fMaxExecutions = theMaxTimes;
  2872.         myPointer->fNextEntry = (VRScriptClickCustomPtr)(**myAppData).fListArray[kVREntry_ClickCustom];
  2873.         (**myAppData).fListArray[kVREntry_ClickCustom] = (VRScriptGenericPtr)myPointer;
  2874.     }
  2875. }
  2876.  
  2877.  
  2878. //////////
  2879. //
  2880. // VRScript_EnlistClickSpriteCommand
  2881. // Install a sprite click command by adding the given information to our linked list.
  2882. //
  2883. //////////
  2884.  
  2885. void VRScript_EnlistClickSpriteCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2886. {
  2887.     VRScriptClickSpritePtr    myPointer;
  2888.     ApplicationDataHdl        myAppData;
  2889.  
  2890.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2891.     if (myAppData == NULL)
  2892.         return;
  2893.  
  2894.     myPointer = (VRScriptClickSpritePtr)NewPtrClear(sizeof(VRScriptClickSprite));
  2895.     if (myPointer != NULL) {
  2896.         myPointer->fEntryType = kVREntry_ClickSprite;
  2897.         myPointer->fNodeID = theNodeID;
  2898.         myPointer->fOptions = theOptions;
  2899.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2900.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2901.         myPointer->fMaxExecutions = theMaxTimes;
  2902.         myPointer->fNextEntry = (VRScriptClickSpritePtr)(**myAppData).fListArray[kVREntry_ClickSprite];
  2903.         (**myAppData).fListArray[kVREntry_ClickSprite] = (VRScriptGenericPtr)myPointer;
  2904.     }
  2905. }
  2906.  
  2907.  
  2908. //////////
  2909. //
  2910. // VRScript_EnlistNodeEntryCommand
  2911. // Install a node-entry command by adding the given information to our linked list.
  2912. //
  2913. //////////
  2914.  
  2915. void VRScript_EnlistNodeEntryCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2916. {
  2917.     VRScriptNodeInPtr        myPointer;
  2918.     ApplicationDataHdl        myAppData;
  2919.  
  2920.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2921.     if (myAppData == NULL)
  2922.         return;
  2923.  
  2924.     myPointer = (VRScriptNodeInPtr)NewPtrClear(sizeof(VRScriptNodeIn));
  2925.     if (myPointer != NULL) {
  2926.         myPointer->fEntryType = kVREntry_NodeEntry;
  2927.         myPointer->fNodeID = theNodeID;
  2928.         myPointer->fOptions = theOptions;
  2929.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2930.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2931.         myPointer->fMaxExecutions = theMaxTimes;
  2932.         myPointer->fNextEntry = (VRScriptNodeInPtr)(**myAppData).fListArray[kVREntry_NodeEntry];
  2933.         (**myAppData).fListArray[kVREntry_NodeEntry] = (VRScriptGenericPtr)myPointer;
  2934.     }
  2935. }
  2936.  
  2937.  
  2938. //////////
  2939. //
  2940. // VRScript_EnlistNodeExitCommand
  2941. // Install a node-exit command by adding the given information to our linked list.
  2942. //
  2943. //////////
  2944.  
  2945. void VRScript_EnlistNodeExitCommand (WindowObject theWindowObject, UInt32 theFromNodeID, UInt32 theToNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2946. {
  2947.     VRScriptNodeOutPtr        myPointer;
  2948.     ApplicationDataHdl        myAppData;
  2949.  
  2950.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2951.     if (myAppData == NULL)
  2952.         return;
  2953.  
  2954.     myPointer = (VRScriptNodeOutPtr)NewPtrClear(sizeof(VRScriptNodeOut));
  2955.     if (myPointer != NULL) {
  2956.         myPointer->fEntryType = kVREntry_NodeExit;
  2957.         myPointer->fOptions = theOptions;
  2958.         myPointer->fFromNodeID = theFromNodeID;
  2959.         myPointer->fToNodeID = theToNodeID;
  2960.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2961.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2962.         myPointer->fMaxExecutions = theMaxTimes;
  2963.         myPointer->fNextEntry = (VRScriptNodeOutPtr)(**myAppData).fListArray[kVREntry_NodeExit];
  2964.         (**myAppData).fListArray[kVREntry_NodeExit] = (VRScriptGenericPtr)myPointer;
  2965.     }
  2966. }
  2967.  
  2968.  
  2969. //////////
  2970. //
  2971. // VRScript_EnlistAngleCommand
  2972. // Install an angle-triggered command by adding the given information to our linked list.
  2973. // Note: this function expects theMinAngle and theMaxAngle to be in *degrees*.
  2974. //
  2975. //////////
  2976.  
  2977. void VRScript_EnlistAngleCommand (WindowObject theWindowObject, UInt32 theKind, UInt32 theNodeID, float theMinAngle, float theMaxAngle, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2978. {
  2979.     VRScriptAtAnglePtr        myPointer;
  2980.     ApplicationDataHdl        myAppData;
  2981.  
  2982.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2983.     if (myAppData == NULL)
  2984.         return;
  2985.  
  2986.     theMinAngle = QTVRUtils_DegreesToRadians(theMinAngle);
  2987.     theMaxAngle = QTVRUtils_DegreesToRadians(theMaxAngle);
  2988.     VRScript_UnpackString(theCmdLine);
  2989.  
  2990.     myPointer = (VRScriptAtAnglePtr)NewPtrClear(sizeof(VRScriptAtAngle));
  2991.     if (myPointer != NULL) {
  2992.         myPointer->fEntryType = theKind;
  2993.         myPointer->fNodeID = theNodeID;
  2994.         myPointer->fOptions = theOptions;
  2995.         myPointer->fMinAngle = theMinAngle;
  2996.         myPointer->fMaxAngle = theMaxAngle;
  2997.         myPointer->fMaxExecutions = theMaxTimes;
  2998.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2999.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  3000.         myPointer->fNextEntry = (VRScriptAtAnglePtr)(**myAppData).fListArray[theKind];
  3001.         (**myAppData).fListArray[theKind] = (VRScriptGenericPtr)myPointer;
  3002.     }
  3003. }
  3004.  
  3005.  
  3006. //////////
  3007. //
  3008. // VRScript_EnlistVariable
  3009. // Install a variable by adding the given information to our linked list.
  3010. //
  3011. //////////
  3012.  
  3013. void VRScript_EnlistVariable (WindowObject theWindowObject, char *theVarName, UInt32 theVarValue)
  3014. {
  3015.     VRScriptVariablePtr        myPointer;
  3016.     ApplicationDataHdl        myAppData;
  3017.  
  3018.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3019.     if (myAppData == NULL)
  3020.         return;
  3021.         
  3022.     myPointer = (VRScriptVariablePtr)NewPtrClear(sizeof(VRScriptVariable));
  3023.     if (myPointer != NULL) {
  3024.         myPointer->fEntryType = kVREntry_Variable;
  3025.         myPointer->fValue = theVarValue;
  3026.         myPointer->fVarName = malloc(strlen(theVarName) + 1);
  3027.         strncpy(myPointer->fVarName, theVarName, strlen(theVarName) + 1);
  3028.         myPointer->fNextEntry = (VRScriptVariablePtr)(**myAppData).fListArray[kVREntry_Variable];
  3029.         (**myAppData).fListArray[kVREntry_Variable] = (VRScriptGenericPtr)myPointer;
  3030.     }
  3031. }
  3032.  
  3033.  
  3034. //////////
  3035. //
  3036. // VRScript_EnlistTransition
  3037. // Install a transition effect by adding the given information to our linked list.
  3038. //
  3039. //////////
  3040.  
  3041. void VRScript_EnlistTransitionEffect (WindowObject theWindowObject, UInt32 theFromNodeID, UInt32 theToNodeID, SInt32 theMaxTimes, OSType theEffectType, long theEffectNum, UInt32 theOptions)
  3042. {
  3043.     VRScriptTransitionPtr    myPointer;
  3044.     ApplicationDataHdl        myAppData;
  3045.  
  3046.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3047.     if (myAppData == NULL)
  3048.         return;
  3049.         
  3050.     myPointer = (VRScriptTransitionPtr)NewPtrClear(sizeof(VRScriptTransition));
  3051.     if (myPointer != NULL) {
  3052.         myPointer->fEntryType = kVREntry_TransitionEffect;
  3053.         myPointer->fOptions = theOptions;
  3054.         myPointer->fFromNodeID = theFromNodeID;
  3055.         myPointer->fToNodeID = theToNodeID;
  3056.         myPointer->fMaxExecutions = theMaxTimes;
  3057.         myPointer->fEffectType = theEffectType;
  3058.         myPointer->fEffectNum = theEffectNum;
  3059.         myPointer->fNumberOfSteps = (long)kDefaultNumSteps;
  3060.         myPointer->fNextEntry = (VRScriptTransitionPtr)(**myAppData).fListArray[kVREntry_TransitionEffect];
  3061.         (**myAppData).fListArray[kVREntry_TransitionEffect] = (VRScriptGenericPtr)myPointer;
  3062.     }
  3063. }
  3064.  
  3065.  
  3066. //////////
  3067. //
  3068. // VRScript_DelistEntry
  3069. // Remove an entry from a linked list.
  3070. //
  3071. //////////
  3072.  
  3073. void VRScript_DelistEntry (WindowObject theWindowObject, VRScriptGenericPtr theEntryPtr)
  3074. {
  3075.     ApplicationDataHdl        myAppData;
  3076.     VRScriptGenericPtr        *myListHead;    // the *address* of the list head
  3077.     
  3078.     if (theEntryPtr == NULL)
  3079.         return;
  3080.     
  3081.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3082.     if (myAppData != NULL) {
  3083.         
  3084.         // get the head of the specified list
  3085.         myListHead = &((**myAppData).fListArray[theEntryPtr->fEntryType]);
  3086.         
  3087.         // get rid of any memory associated with this entry
  3088.         switch (theEntryPtr->fEntryType) {
  3089.             case kVREntry_Sound:
  3090.                 VRSound_DumpEntryMem((VRScriptSoundPtr)theEntryPtr);            break;
  3091.             case kVREntry_QTMovie: 
  3092.                 VRMoov_DumpEntryMem((VRScriptMoviePtr)theEntryPtr);                break;
  3093.             case kVREntry_QD3DObject: 
  3094. #if QD3D_AVAIL
  3095.                 VR3DObjects_DumpEntryMem((VRScript3DObjPtr)theEntryPtr);
  3096. #endif
  3097.                 break;
  3098.             case kVREntry_OverlayPicture: 
  3099.                 VRPicture_DumpEntryMem((VRScriptPicturePtr)theEntryPtr);        break;
  3100.             case kVREntry_TimedCommand: 
  3101.                 free(((VRScriptAtTimePtr)theEntryPtr)->fCommandLine);            break;
  3102.             case kVREntry_QuitCommand: 
  3103.                 free(((VRScriptAtQuitPtr)theEntryPtr)->fCommandLine);            break;
  3104.             case kVREntry_MouseOverHS: 
  3105.                 free(((VRScriptAtMOHSPtr)theEntryPtr)->fCommandLine);            break;
  3106.             case kVREntry_ClickHS: 
  3107.                 free(((VRScriptClickHSPtr)theEntryPtr)->fCommandLine);            break;
  3108.             case kVREntry_ClickCustom: 
  3109.                 free(((VRScriptClickCustomPtr)theEntryPtr)->fCommandLine);        break;
  3110.             case kVREntry_ClickSprite: 
  3111.                 free(((VRScriptClickSpritePtr)theEntryPtr)->fCommandLine);        break;
  3112.             case kVREntry_NodeEntry: 
  3113.                 free(((VRScriptNodeInPtr)theEntryPtr)->fCommandLine);            break;
  3114.             case kVREntry_NodeExit: 
  3115.                 free(((VRScriptNodeOutPtr)theEntryPtr)->fCommandLine);            break;
  3116.             case kVREntry_PanAngleCmd: 
  3117.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  3118.             case kVREntry_TiltAngleCmd: 
  3119.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  3120.             case kVREntry_FOVAngleCmd: 
  3121.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  3122.             case kVREntry_Variable: 
  3123.                 free(((VRScriptVariablePtr)theEntryPtr)->fVarName);                break;
  3124.             case kVREntry_TransitionEffect: 
  3125.                 VREffects_DumpEntryMem((VRScriptTransitionPtr)theEntryPtr);        break;
  3126.             case kVREntry_Generic: 
  3127.             case kVREntry_Unknown: 
  3128.             default: 
  3129.                 return;
  3130.                 break;
  3131.         }
  3132.     
  3133.         // now drop the specified entry from the correct list
  3134.  
  3135.         if (*myListHead == theEntryPtr) {
  3136.             // the entry to remove is the head of the list; make the next entry the head    
  3137.             *myListHead = theEntryPtr->fNextEntry;
  3138.         } else {
  3139.             // the entry to remove is not the head of the list;
  3140.             // walk the list until we find the entry *before* the one to be removed
  3141.             VRScriptGenericPtr        myPointer;
  3142.  
  3143.             myPointer = *myListHead;
  3144.             while (myPointer != NULL) {
  3145.                 if (myPointer->fNextEntry == theEntryPtr) {
  3146.                     myPointer->fNextEntry = theEntryPtr->fNextEntry;
  3147.                     break;
  3148.                 }
  3149.                 myPointer = (VRScriptGenericPtr)(myPointer->fNextEntry);
  3150.             }
  3151.         }
  3152.     }
  3153.     
  3154.     DisposePtr((Ptr)theEntryPtr);
  3155. }
  3156.  
  3157.  
  3158. //////////
  3159. //
  3160. // VRScript_DeleteListOfType
  3161. // Delete the list containing entries of the specified type.
  3162. //
  3163. //////////
  3164.  
  3165. void VRScript_DeleteListOfType (WindowObject theWindowObject, UInt32 theEntryType)
  3166. {
  3167.     ApplicationDataHdl        myAppData;
  3168.     VRScriptGenericPtr        myPointer;
  3169.     
  3170.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3171.     if (myAppData == NULL)
  3172.         return;
  3173.         
  3174.     // get the head of specified list
  3175.     myPointer = (**myAppData).fListArray[theEntryType];
  3176.     while (myPointer != NULL) {
  3177.         VRScriptGenericPtr        myNext;
  3178.         
  3179.         myNext = myPointer->fNextEntry;
  3180.         
  3181.         // get rid of any memory associated with this entry
  3182.         switch (theEntryType) {
  3183.             case kVREntry_Sound: 
  3184.                 VRSound_DumpEntryMem((VRScriptSoundPtr)myPointer);                break;
  3185.             case kVREntry_QTMovie: 
  3186.                 VRMoov_DumpEntryMem((VRScriptMoviePtr)myPointer);                break;
  3187.             case kVREntry_QD3DObject: 
  3188. #if QD3D_AVAIL
  3189.                 VR3DObjects_DumpEntryMem((VRScript3DObjPtr)myPointer);
  3190. #endif
  3191.                                                                                 break;
  3192.             case kVREntry_OverlayPicture: 
  3193.                 VRPicture_DumpEntryMem((VRScriptPicturePtr)myPointer);            break;
  3194.             case kVREntry_TimedCommand: 
  3195.                 free(((VRScriptAtTimePtr)myPointer)->fCommandLine);                break;
  3196.             case kVREntry_QuitCommand: 
  3197.                 free(((VRScriptAtQuitPtr)myPointer)->fCommandLine);                break;
  3198.             case kVREntry_MouseOverHS: 
  3199.                 free(((VRScriptAtMOHSPtr)myPointer)->fCommandLine);                break;
  3200.             case kVREntry_ClickHS: 
  3201.                 free(((VRScriptClickHSPtr)myPointer)->fCommandLine);            break;
  3202.             case kVREntry_ClickCustom: 
  3203.                 free(((VRScriptClickCustomPtr)myPointer)->fCommandLine);        break;
  3204.             case kVREntry_ClickSprite: 
  3205.                 free(((VRScriptClickSpritePtr)myPointer)->fCommandLine);        break;
  3206.             case kVREntry_NodeEntry: 
  3207.                 free(((VRScriptNodeInPtr)myPointer)->fCommandLine);                break;
  3208.             case kVREntry_NodeExit: 
  3209.                 free(((VRScriptNodeOutPtr)myPointer)->fCommandLine);            break;
  3210.             case kVREntry_PanAngleCmd: 
  3211.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3212.             case kVREntry_TiltAngleCmd: 
  3213.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3214.             case kVREntry_FOVAngleCmd: 
  3215.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3216.             case kVREntry_Variable: 
  3217.                 free(((VRScriptVariablePtr)myPointer)->fVarName);                break;
  3218.             case kVREntry_TransitionEffect: 
  3219.                 VREffects_DumpEntryMem((VRScriptTransitionPtr)myPointer);        break;
  3220.             case kVREntry_Generic: 
  3221.             case kVREntry_Unknown: 
  3222.             default: 
  3223.                 return;
  3224.         }
  3225.         
  3226.         DisposePtr((Ptr)myPointer);
  3227.         myPointer = myNext;
  3228.     }
  3229.     
  3230.     (**myAppData).fListArray[theEntryType] = NULL;
  3231. }
  3232.  
  3233.  
  3234. //////////
  3235. //
  3236. // VRScript_DeleteAllLists
  3237. // Delete all lists used by this window.
  3238. //
  3239. //////////
  3240.  
  3241. void VRScript_DeleteAllLists (WindowObject theWindowObject)
  3242. {
  3243.     UInt32        myCount;
  3244.     
  3245.     for (myCount = kVRScript_FirstEntryType; myCount <= kVRScript_FinalEntryType; myCount++)
  3246.         VRScript_DeleteListOfType(theWindowObject, myCount);
  3247. }
  3248.  
  3249.  
  3250. //////////
  3251. //
  3252. // VRScript_GetObjectByEntryID
  3253. // Get the (first) list entry of the specified type having a specified entry ID.
  3254. //
  3255. //////////
  3256.  
  3257. VRScriptGenericPtr VRScript_GetObjectByEntryID (WindowObject theWindowObject, UInt32 theEntryType, UInt32 theEntryID)
  3258. {
  3259.     ApplicationDataHdl    myAppData;
  3260.     VRScriptGenericPtr    myPointer = NULL;
  3261.  
  3262.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);    
  3263.     if (myAppData == NULL)
  3264.         return(NULL);
  3265.     
  3266.     // walk our linked list to find the target object
  3267.     myPointer = (**myAppData).fListArray[theEntryType];
  3268.     while (myPointer != NULL) {
  3269.         if (myPointer->fEntryID == theEntryID)
  3270.             return(myPointer);
  3271.         myPointer = myPointer->fNextEntry;
  3272.     }
  3273.     
  3274.     return(NULL);
  3275. }
  3276.  
  3277.  
  3278. //////////
  3279. //
  3280. // VRScript_GetVariableEntry
  3281. // Get the (first) variable having the specified name.
  3282. //
  3283. //////////
  3284.  
  3285. VRScriptVariablePtr VRScript_GetVariableEntry (WindowObject theWindowObject, char *theVarName)
  3286. {
  3287.     ApplicationDataHdl    myAppData;
  3288.     VRScriptVariablePtr    myPointer = NULL;
  3289.  
  3290.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);    
  3291.     if (myAppData == NULL)
  3292.         return(NULL);
  3293.     
  3294.     // walk our linked list to find the target object
  3295.     myPointer = (VRScriptVariablePtr)(**myAppData).fListArray[kVREntry_Variable];
  3296.     while (myPointer != NULL) {
  3297.         if (strcmp(myPointer->fVarName, theVarName) == 0)
  3298.             return(myPointer);
  3299.         myPointer = myPointer->fNextEntry;
  3300.     }
  3301.     
  3302.     return(NULL);
  3303. }
  3304.  
  3305.  
  3306. //////////
  3307. //
  3308. // VRScript_InstallHotSpotInterceptProc
  3309. // Install an intercept procedure for handling hot spot triggerings.
  3310. //
  3311. //////////
  3312.  
  3313. void VRScript_InstallHotSpotInterceptProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3314. {
  3315.     QTVRInterceptUPP        myInterceptProc;
  3316.     
  3317.     myInterceptProc = NewQTVRInterceptProc(VRScript_HotSpotInterceptProc);
  3318.     QTVRInstallInterceptProc(theInstance, kQTVRTriggerHotSpotSelector, myInterceptProc, (long)theWindowObject, 0);
  3319. }
  3320.  
  3321.  
  3322. //////////
  3323. //
  3324. // VRScript_InstallMouseOverHotSpotProc
  3325. // Install an intercept procedure for handling mouse-over hot spots.
  3326. //
  3327. //////////
  3328.  
  3329. void VRScript_InstallMouseOverHotSpotProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3330. {
  3331.     QTVRMouseOverHotSpotUPP        myInterceptProc;
  3332.     
  3333.     myInterceptProc = NewQTVRMouseOverHotSpotProc(VRScript_MouseOverHotSpotProc);
  3334.     QTVRSetMouseOverHotSpotProc(theInstance, myInterceptProc, (long)theWindowObject, 0);
  3335. }
  3336.  
  3337.  
  3338. //////////
  3339. //
  3340. // VRScript_InstallPrescreenRoutine
  3341. // Install a prescreen buffer imaging complete procedure.
  3342. //
  3343. //////////
  3344.  
  3345. void VRScript_InstallPrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3346. {
  3347.     ApplicationDataHdl    myAppData;
  3348.  
  3349.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3350.     if (myAppData != NULL)
  3351.         QTVRSetPrescreenImagingCompleteProc(theInstance, (**myAppData).fPrescreenProc, (SInt32)theWindowObject, 0);
  3352. }
  3353.  
  3354.  
  3355. //////////
  3356. //
  3357. // VRScript_InstallBackBufferImagingProc
  3358. // Install a back buffer imaging procedure.
  3359. // (This routine might sometimes be called to move or resize the area of interest within the panorama.)
  3360. //
  3361. //////////
  3362.  
  3363. void VRScript_InstallBackBufferImagingProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3364. {
  3365.     ApplicationDataHdl        myAppData = NULL;
  3366.     QTVRAreaOfInterest        myArea;
  3367.     float                    myWidth, myHeight;
  3368.     VRScriptMoviePtr        myPointer = NULL;
  3369.     OSErr                    myErr = paramErr;
  3370.     
  3371.     //////////
  3372.     //
  3373.     // initialize; clean up any existing back buffer procedure
  3374.     //
  3375.     //////////
  3376.     
  3377.     if ((theInstance == NULL) || (theWindowObject == NULL)) 
  3378.         return;
  3379.  
  3380.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3381.     if (myAppData == NULL) 
  3382.         return;
  3383.  
  3384.     HLock((Handle)myAppData);
  3385.     
  3386.     // remove any existing back buffer imaging procedure
  3387.     if ((**myAppData).fBackBufferProc != NULL)
  3388.         QTVRSetBackBufferImagingProc((**theWindowObject).fInstance, NULL, 0, NULL, 0);
  3389.  
  3390.     //////////
  3391.     //
  3392.     // set the area of interest
  3393.     //
  3394.     // the panAngle and tiltAngle fields define the top-left corner, in panorama space, of the area of interest;
  3395.     // so here we do not have to worry about whether the back buffer is oriented vertically or horizontally
  3396.     //
  3397.     //////////
  3398.     
  3399.     myPointer = VRMoov_GetEmbeddedVideo(theWindowObject);
  3400.     if (myPointer == NULL)
  3401.         goto bail;
  3402.     
  3403.     myWidth = myPointer->fMovieWidth * myPointer->fMovieScale;
  3404.     myHeight = myWidth * (((float)myPointer->fMovieBox.bottom) / ((float)myPointer->fMovieBox.right));
  3405.  
  3406.     if (myPointer->fUseMovieCenter) {
  3407.         // use the stored movie center
  3408.         myArea.panAngle = myPointer->fMovieCenter.x + (myWidth/2);
  3409.         myArea.tiltAngle = myPointer->fMovieCenter.y + (myHeight/2);
  3410.     } else {
  3411.         // center the movie on the current pan and tilt angles
  3412.         myArea.panAngle = QTVRGetPanAngle(theInstance) + (myWidth/2);
  3413.         myArea.tiltAngle = QTVRGetTiltAngle(theInstance) + (myHeight/2);
  3414.     }
  3415.     
  3416.     myArea.width = myWidth;
  3417.     myArea.height = myHeight;
  3418.  
  3419.     // *** insertion (B) ***
  3420.     
  3421.     //////////
  3422.     //
  3423.     // set the back buffer flags and install the back buffer procedure
  3424.     //
  3425.     //////////
  3426.     
  3427.     // make sure we get called on every idle event, so we can keep playing the embedded movie;
  3428.     // also make sure we get called on every back buffer update
  3429.     if (myPointer->fCompositeMovie)
  3430.         myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate | kQTVRBackBufferAlwaysRefresh;
  3431.     else
  3432.         myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate;
  3433.     
  3434.     // if the back buffer is oriented horizontally, set the appropriate flag
  3435.     if ((**myAppData).fBackBufferIsHoriz)
  3436.         myArea.flags |= kQTVRBackBufferHorizontal;
  3437.  
  3438.     // install our procedure
  3439.     myErr = QTVRSetBackBufferImagingProc(theInstance, (**myAppData).fBackBufferProc, 1, &myArea, (SInt32)theWindowObject);
  3440.  
  3441. bail:
  3442.     // make sure we successfully installed the procedure;
  3443.     // if an error occurred, clear the back-buffer imaging procedure
  3444.     if (myErr != noErr)
  3445.         QTVRSetBackBufferImagingProc((**theWindowObject).fInstance, NULL, 0, NULL, 0);
  3446.     
  3447.     HUnlock((Handle)myAppData);
  3448. }
  3449.     
  3450.  
  3451. //////////
  3452. //
  3453. // VRScript_InstallInterceptRoutine
  3454. // Install our QTVR intercept procedure.
  3455. //
  3456. //////////
  3457.  
  3458. void VRScript_InstallInterceptRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3459. {
  3460.     QTVRInterceptUPP    myInterceptProc;
  3461.     
  3462.     myInterceptProc = NewQTVRInterceptProc(VRScript_InterceptRoutine);    
  3463.     
  3464.     // we'll just use the same intercept proc for each intercepted procedure
  3465.     QTVRInstallInterceptProc(theInstance, kQTVRSetPanAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3466.     QTVRInstallInterceptProc(theInstance, kQTVRSetTiltAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3467.     QTVRInstallInterceptProc(theInstance, kQTVRSetFieldOfViewSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3468.     QTVRInstallInterceptProc(theInstance, kQTVRSetViewCenterSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3469. }
  3470.  
  3471.  
  3472. //////////
  3473. //
  3474. // VRScript_HotSpotInterceptProc
  3475. // An intercept procedure for handling hot spot triggerings.
  3476. //
  3477. //////////
  3478.  
  3479. PASCAL_RTN void VRScript_HotSpotInterceptProc (QTVRInstance theInstance, QTVRInterceptPtr theMsg, WindowObject theWindowObject, Boolean *theCancel)
  3480. {
  3481.     VRScriptClickHSPtr        myPointer;
  3482.     VRScriptClickHSPtr        myNext;
  3483.     ApplicationDataHdl        myAppData;
  3484.     UInt32                    myNodeID;
  3485.     UInt32                    myHotSpotID;
  3486.     OSType                    myType;
  3487.     Boolean                    myCancelLink = false;
  3488.     
  3489.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3490.     if (myAppData == NULL)
  3491.         return;
  3492.  
  3493.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3494.     myHotSpotID = (UInt32)(theMsg->parameter[0]);
  3495.     
  3496.     // get the type of the hot spot, given its ID
  3497.     QTVRUtils_GetHotSpotType(theInstance, myNodeID, myHotSpotID, &myType);
  3498.     
  3499.     // walk the linked list and find any commands for this hot spot
  3500.     myPointer = (VRScriptClickHSPtr)(**myAppData).fListArray[kVREntry_ClickHS];
  3501.     while (myPointer != NULL) {
  3502.         myNext = myPointer->fNextEntry;
  3503.         
  3504.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3505.             if (((myPointer->fSelectByID) && (myPointer->fHotSpotID == myHotSpotID))    // hot spot is specified by ID
  3506.             || ((!myPointer->fSelectByID) && (myPointer->fHotSpotType == myType))) {    // hot spot is specified by type
  3507.                 if (myPointer->fOptions != 0)
  3508.                     myCancelLink = true;
  3509.                 VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3510.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3511.             }
  3512.  
  3513.         myPointer = myNext;
  3514.     }
  3515.  
  3516.     *theCancel = myCancelLink;
  3517. }
  3518.  
  3519.  
  3520. ///////////
  3521. //
  3522. // VRScript_PrescreenRoutine
  3523. // A prescreen buffer imaging completion routine:
  3524. //     * alter the position of the 3D sound listener based on the user's panning or tilting
  3525. //     * set balance and volume of embedded QuickTime movie
  3526. //    * draw the rendered 3D scene into the prescreen buffer
  3527. //    * draw any enlisted overlay picture into the prescreen buffer
  3528. //
  3529. //////////
  3530.  
  3531. PASCAL_RTN OSErr VRScript_PrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3532. {
  3533.     float                myPan;
  3534.     float                myTilt;
  3535.     float                myFOV;
  3536.     UInt32                myNodeID;
  3537.     ApplicationDataHdl    myAppData;
  3538.  
  3539.     // get the application-specific data associated with the window
  3540.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3541.     if (myAppData == NULL)
  3542.         return(paramErr);
  3543.         
  3544.     // get the current environment
  3545.     myPan = QTVRGetPanAngle(theInstance);
  3546.     myTilt = QTVRGetTiltAngle(theInstance);
  3547.     myFOV = QTVRGetFieldOfView(theInstance);
  3548.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3549.  
  3550.     // process any localized sounds in the current node
  3551.     if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged) 
  3552.         if ((**myAppData).fListArray[kVREntry_Sound] != NULL) {
  3553.             if (gHasSoundSprockets) {
  3554. #if SOUNDSPROCKET_AVAIL
  3555.                 TQ3Vector3D            myOrientation;
  3556.             
  3557.                 // figure out the orientation    
  3558.                 myOrientation.x = -sin(myPan) * cos(myTilt);
  3559.                 myOrientation.y = sin(myTilt);
  3560.                 myOrientation.z = -cos(myPan) * cos(myTilt);
  3561.                     
  3562.                 // set the new orientation of the listener
  3563.                 SSpListener_SetOrientation((**myAppData).fListener, &myOrientation);
  3564.                 // update the virtual audio environment
  3565.                 VRSound_Update3DSoundEnv(theWindowObject);
  3566. #endif
  3567.             } else {
  3568.                 // we don't have SoundSprockets, so....
  3569.                 // handle sound balance and volume attentuation ourselves
  3570.                 VRSound_SetBalanceAndVolume(theWindowObject, myPan, myTilt);
  3571.             }
  3572.         }
  3573.         
  3574. #if QD3D_AVAIL
  3575.     // process any 3D objects in the current node
  3576.     if (gHasQuickDraw3D)
  3577.         if ((**myAppData).fListArray[kVREntry_QD3DObject] != NULL)
  3578.             VR3DObjects_PrescreenRoutine(theInstance, theWindowObject);
  3579. #endif
  3580.  
  3581.     // handle directionality and volume attenuation for QuickTime movie sound and texture-mapped QuickTime movie sound
  3582.     if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged)
  3583.         if (((**myAppData).fListArray[kVREntry_QTMovie] != NULL) || ((**myAppData).fListArray[kVREntry_QD3DObject] != NULL))
  3584.             VRMoov_SetAllBalanceAndVolume(theWindowObject, myPan, myTilt);
  3585.  
  3586.     // draw any overlay pictures
  3587.     VRPicture_DrawNodePictures(theWindowObject);
  3588.  
  3589.     // reset our flags
  3590.     (**myAppData).fViewHasChanged = false;
  3591.     (**myAppData).fSoundHasChanged = false;
  3592.     
  3593.     return(noErr);
  3594. }
  3595.  
  3596.  
  3597. //////////
  3598. //
  3599. // VRScript_BackBufferImagingProc
  3600. // A back buffer imaging procedure:
  3601. //    * handle any QuickTime movies playing in the back buffer
  3602. //    * handle any pictures embedded in the back buffer [to be provided]
  3603. //
  3604. //////////
  3605.  
  3606. PASCAL_RTN OSErr VRScript_BackBufferImagingProc (QTVRInstance theInstance, Rect *theRect, UInt16 theAreaIndex, UInt32 theFlagsIn, UInt32 *theFlagsOut, WindowObject theWindowObject)
  3607. {
  3608. #pragma unused(theAreaIndex)
  3609.  
  3610.     ApplicationDataHdl        myAppData = NULL;
  3611.     OSErr                    myErr = noErr;
  3612.     
  3613.     if ((theInstance == NULL) || (theWindowObject == NULL)) 
  3614.         return(paramErr);
  3615.  
  3616.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3617.     if (myAppData == NULL) 
  3618.         return(paramErr);
  3619.  
  3620.     // if we've got an active movie to play, do so
  3621.     if (VRMoov_GetEmbeddedVideo(theWindowObject) != NULL)
  3622.         myErr = VRMoov_BackBufferImagingProc(theInstance, theRect, theAreaIndex, theFlagsIn, theFlagsOut, theWindowObject);
  3623.             
  3624.     return(myErr);
  3625. }
  3626.  
  3627.  
  3628. //////////
  3629. //
  3630. // VRScript_InterceptRoutine
  3631. // An intercept routine:
  3632. //     * signal that the view parameters have changed
  3633. //
  3634. //////////
  3635.  
  3636. PASCAL_RTN void VRScript_InterceptRoutine (QTVRInstance theInstance, QTVRInterceptPtr theMsg, WindowObject theWindowObject, Boolean *cancel)
  3637. {
  3638. #pragma unused(theInstance)
  3639.  
  3640.     Boolean                myCancelInterceptedProc = false;    // true == do NOT call thru; false == call thru
  3641.     ApplicationDataHdl    myAppData;
  3642.     
  3643.     *cancel = myCancelInterceptedProc;
  3644.  
  3645.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3646.     if (myAppData == NULL)
  3647.         return;
  3648.  
  3649.     switch (theMsg->selector) {
  3650.         case kQTVRSetPanAngleSelector:
  3651.         case kQTVRSetTiltAngleSelector:
  3652.         case kQTVRSetFieldOfViewSelector:
  3653.         case kQTVRSetViewCenterSelector:
  3654.             (**myAppData).fViewHasChanged = true;
  3655.             break;
  3656.             
  3657.         default:
  3658.             break;
  3659.     }
  3660.     
  3661. }
  3662.  
  3663.  
  3664. //////////
  3665. //
  3666. // VRScript_EnteringNodeProc
  3667. // A node-entering procedure:
  3668. //    * initialize node-specific global variables (e.g., the node timer)
  3669. //    * execute the standard node-entry procedure
  3670. //    * execute any node-entry commands
  3671. //    * execute any custom transitions from the previous node to the current node
  3672. //
  3673. //////////
  3674.  
  3675. PASCAL_RTN OSErr VRScript_EnteringNodeProc (QTVRInstance theInstance, UInt32 theNodeID, WindowObject theWindowObject)
  3676. {
  3677.     VRScriptNodeInPtr        myPointer = NULL;
  3678.     VRScriptNodeInPtr        myNext = NULL;
  3679.     ApplicationDataHdl        myAppData;
  3680.  
  3681.     // initialize our node timer
  3682.     gNodeStartingTime = TickCount();
  3683.  
  3684.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3685.     if (myAppData == NULL)
  3686.         return(paramErr);
  3687.  
  3688.     // call the standard node-entry procedure
  3689.     if ((**theWindowObject).fController != NULL)
  3690.         QTVRUtils_StandardEnteringNodeProc(theInstance, theNodeID, (**theWindowObject).fController);
  3691.  
  3692.     // node-entry commands might invoke QTVRUpdate, so enable update-streaming
  3693.     if (QTVRUtils_IsPanoNode(theInstance))
  3694.         QTVRBeginUpdateStream(theInstance, kQTVRCurrentMode);
  3695.  
  3696.     // walk the node-entry command list and execute any that apply to this node
  3697.     myPointer = (VRScriptNodeInPtr)(**myAppData).fListArray[kVREntry_NodeEntry];
  3698.     while (myPointer != NULL) {
  3699.         myNext = myPointer->fNextEntry;
  3700.         
  3701.         if ((myPointer->fNodeID == theNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  3702.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3703.             VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3704.         }
  3705.     
  3706.         myPointer = myNext;
  3707.     }
  3708.     
  3709.     // disable update-streaming, if previously enabled
  3710.     if (QTVRUtils_IsPanoNode(theInstance))
  3711.         QTVREndUpdateStream(theInstance);
  3712.  
  3713.     // if a node transition effect is pending, force the movie image to be updated;
  3714.     // this draws the destination image into an offscreen GWorld
  3715.     if ((**myAppData).fActiveTransition != NULL) {
  3716.         MoviesTask((**theWindowObject).fMovie, 0L);
  3717.         
  3718.         // execute any custom transitions from the previous node to the current node
  3719.         if (gHasQTVideoEffects)
  3720.             VREffects_RunTransitionEffect(theWindowObject);
  3721.     }
  3722.  
  3723.     return(noErr);
  3724. }
  3725.  
  3726.  
  3727. //////////
  3728. //
  3729. // VRScript_LeavingNodeProc
  3730. // A node-leaving procedure:
  3731. //    * execute any node-exit commands
  3732. //    * stop any sounds attached to the current node
  3733. //    * dump any pictures attached to the current node
  3734. //    * dump any movies attached to the current node
  3735. //    * dump any unexpired AtTime commands that shouldn't be orphaned
  3736. //    * set up for any custom transitions from the current node to the target node
  3737.  
  3738. //////////
  3739.  
  3740. PASCAL_RTN OSErr VRScript_LeavingNodeProc (QTVRInstance theInstance, UInt32 fromNodeID, UInt32 toNodeID, Boolean *theCancel, WindowObject theWindowObject)
  3741. {
  3742.     VRScriptNodeOutPtr        myPointer;
  3743.     VRScriptNodeOutPtr        myNext;
  3744.     ApplicationDataHdl        myAppData;
  3745.     Boolean                    myCancelExit = false;
  3746.     
  3747.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3748.     if (myAppData == NULL)
  3749.         return(paramErr);
  3750.         
  3751.     // walk the node-leaving command list and execute any that apply to this node
  3752.     myPointer = (VRScriptNodeOutPtr)(**myAppData).fListArray[kVREntry_NodeExit];
  3753.     while (myPointer != NULL) {
  3754.         myNext = myPointer->fNextEntry;
  3755.         
  3756.         if ((myPointer->fFromNodeID == fromNodeID) || (myPointer->fFromNodeID == kVRAnyNode))
  3757.             if ((myPointer->fToNodeID == toNodeID) || (myPointer->fToNodeID == kVRAnyNode)) {
  3758.                 VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3759.                 if (myPointer->fOptions != 0)
  3760.                     myCancelExit = true;
  3761.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3762.             }
  3763.     
  3764.         myPointer = myNext;
  3765.     }
  3766.     
  3767.     // set output parameter to indicate whether we're leaving the node or not
  3768.     *theCancel = myCancelExit;
  3769.     
  3770.     // if we're not leaving the node, just return
  3771.     if (myCancelExit)
  3772.         return(noErr);
  3773.     
  3774.     // set up for any custom transitions from the current node to the target node
  3775.     // (since we're going to get the first frame of our effect by rendering a frame
  3776.     // of the movie into an offscreen GWorld, we need to do this before we dump the
  3777.     // node pictures, movies, etc.)
  3778.     if (gHasQTVideoEffects)
  3779.         VREffects_SetupTransitionEffect(theWindowObject, fromNodeID, toNodeID);
  3780.     
  3781.     // if we really are leaving the node, dump node-specific sounds, pictures, and movies
  3782.     VRSound_DumpNodeSounds(theWindowObject);
  3783.     VRPicture_DumpNodePictures(theWindowObject);
  3784.     VRMoov_DumpNodeMovies(theWindowObject);
  3785.     
  3786.     // dump any unexpired time-based commands that are marked as to-be-killed
  3787.     VRScript_DumpUnexpiredCommands(theWindowObject, fromNodeID);
  3788.     
  3789.     // work around a bug in QTVR: 
  3790.     // moving from a panoramic node to an object node effectively hoses the prescreen routine,
  3791.     // so we need to reinstall that routine if we're moving from an object to a panoramic node
  3792.     if (QTVRGetNodeType(theInstance, fromNodeID) == kQTVRObjectType)
  3793.         if (QTVRGetNodeType(theInstance, toNodeID) == kQTVRPanoramaType)
  3794.             VRScript_InstallPrescreenRoutine(theInstance, theWindowObject);
  3795.  
  3796.     return(noErr);
  3797. }
  3798.  
  3799.  
  3800. //////////
  3801. //
  3802. // VRScript_MouseOverHotSpotProc
  3803. // Walk through our linked list of mouse-over hot spot commands and see whether any need to be executed.
  3804. //
  3805. // We support hot spots specified by ID (myPointer->fSelectByID == true) or by type (myPointer->fSelectByID == false).
  3806. //
  3807. //////////
  3808.  
  3809. PASCAL_RTN OSErr VRScript_MouseOverHotSpotProc (QTVRInstance theInstance, UInt32 theHotSpotID, UInt32 theFlags, WindowObject theWindowObject)
  3810. {
  3811.     VRScriptAtMOHSPtr        myPointer;
  3812.     VRScriptAtMOHSPtr        myNext;
  3813.     ApplicationDataHdl        myAppData;
  3814.     UInt32                    myNodeID;
  3815.     OSType                    myType;
  3816.     
  3817.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3818.     if (myAppData == NULL)
  3819.         return(paramErr);
  3820.     
  3821.     // get the current node ID
  3822.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3823.     
  3824.     // get the type of the hot spot, given its ID
  3825.     QTVRUtils_GetHotSpotType(theInstance, myNodeID, theHotSpotID, &myType);
  3826.     
  3827.     // walk the linked list and find any commands for this hot spot
  3828.     myPointer = (VRScriptAtMOHSPtr)(**myAppData).fListArray[kVREntry_MouseOverHS];
  3829.     while (myPointer != NULL) {
  3830.         myNext = myPointer->fNextEntry;
  3831.         
  3832.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3833.             if (((myPointer->fSelectByID) && (myPointer->fHotSpotID == theHotSpotID))    // hot spot is specified by ID
  3834.             || ((!myPointer->fSelectByID) && (myPointer->fHotSpotType == myType)))        // hot spot is specified by type
  3835.                 if (myPointer->fOptions == theFlags) {
  3836.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3837.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3838.                 }
  3839.     
  3840.         myPointer = myNext;
  3841.     }
  3842.  
  3843.     return(noErr);        // returning noErr means QTVR should do its normal mouse-over-hot-spot stuff
  3844. }
  3845.  
  3846.  
  3847. //////////
  3848. //
  3849. // VRScript_MoviePrePrerollCompleteProc
  3850. // A completion procedure for pre-prerolling movies.
  3851. //
  3852. //////////
  3853.  
  3854. PASCAL_RTN void VRScript_MoviePrePrerollCompleteProc (Movie theMovie, OSErr thePrerollErr, void *theRefcon)
  3855. {
  3856. #pragma unused(thePrerollErr, theRefcon)
  3857.     StartMovie(theMovie);
  3858. }
  3859.  
  3860.  
  3861. //////////
  3862. //
  3863. // VRScript_CheckForTimedCommands
  3864. // Walk through our linked list of timed commands and see whether any need to be executed.
  3865. //
  3866. //////////
  3867.  
  3868. void VRScript_CheckForTimedCommands (WindowObject theWindowObject)
  3869. {
  3870.     ApplicationDataHdl        myAppData;
  3871.     UInt32                    myNodeID;
  3872.     VRScriptAtTimePtr        myPointer;
  3873.     VRScriptAtTimePtr        myNext;
  3874.     Boolean                    myRunCommand;
  3875.  
  3876.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3877.     if (myAppData == NULL)
  3878.         return;
  3879.  
  3880.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3881.     
  3882.     // walk the linked list and find any commands ready to be executed
  3883.     myPointer = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  3884.     while (myPointer != NULL) {
  3885.         myNext = myPointer->fNextEntry;
  3886.         myRunCommand = false;
  3887.  
  3888.         switch (myPointer->fMode) {
  3889.             case kVRUseNodeTime:
  3890.                 if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3891.                     myRunCommand = (gNodeElapsedTime >= myPointer->fTime);
  3892.                 break;
  3893.             case kVRUseAbsoluteTime:
  3894.                 myRunCommand = (gAbsoluteElapsedTime >= myPointer->fTime);
  3895.                 break;
  3896.             case kVRUseInstallTime:
  3897.                 myRunCommand = ((gAbsoluteElapsedTime - myPointer->fTimeInstalled) >= myPointer->fTime);
  3898.                 break;
  3899.         }
  3900.  
  3901.         if (myRunCommand) {
  3902.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3903.             if (myPointer->fRepeat) {
  3904.                 myPointer->fTime += myPointer->fPeriod;
  3905.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3906.             } else {
  3907.                 VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)myPointer);
  3908.             }
  3909.         }
  3910.         
  3911.         myPointer = myNext;
  3912.     }
  3913. }
  3914.  
  3915.  
  3916. //////////
  3917. //
  3918. // VRScript_CheckForClickCustomButtonCommands
  3919. // Walk through our linked list of custom-button-click commands and see whether any need to be executed.
  3920. //
  3921. //////////
  3922.  
  3923. void VRScript_CheckForClickCustomButtonCommands (WindowObject theWindowObject, EventRecord *theEvent)
  3924. {
  3925.     ApplicationDataHdl        myAppData;
  3926.     UInt32                    myNodeID;
  3927.     VRScriptClickCustomPtr    myPointer = NULL;
  3928.     VRScriptClickCustomPtr    myNext = NULL;
  3929.     UInt32                    myStartTicks = theEvent->when;
  3930.     UInt32                    myElapsedTime = 0;
  3931.     UInt32                    myIgnoredTime;
  3932.     
  3933.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3934.     if (myAppData == NULL)
  3935.         return;
  3936.  
  3937.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3938.     
  3939.     // walk the custom-button-click command linked list and execute any that apply to this node
  3940.     myPointer = (VRScriptClickCustomPtr)(**myAppData).fListArray[kVREntry_ClickCustom];
  3941.     while (myPointer != NULL) {
  3942.         myNext = myPointer->fNextEntry;
  3943.         
  3944.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  3945.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3946.             VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3947.         }
  3948.     
  3949.         myPointer = myNext;
  3950.     }
  3951.     
  3952.     // we want the button to be depressed for at least kMyButtonDelay ticks, so (perhaps) let's wait before returning
  3953.     myElapsedTime = TickCount() - myStartTicks;
  3954.     if (myElapsedTime < kMyButtonDelay)
  3955.         Delay(kMyButtonDelay - myElapsedTime, &myIgnoredTime);
  3956. }
  3957.  
  3958.  
  3959. //////////
  3960. //
  3961. // VRScript_CheckForClickSpriteCommands
  3962. // Determine whether a mouse click is on a sprite; return true if it is, false otherwise.
  3963. //
  3964. // This routine is intended to be called from your movie controller action filter function,
  3965. // in response to mcActionMouseDown actions.
  3966. //
  3967. //////////
  3968.  
  3969. Boolean VRScript_CheckForClickSpriteCommands (WindowObject theWindowObject, EventRecord *theEvent)
  3970. {
  3971.     ApplicationDataHdl        myAppData;
  3972.     MediaHandler            myHandler = NULL;
  3973.     Boolean                    isHandled = false;
  3974.     long                    myFlags = 0L;
  3975.     QTAtomID                myAtomID = 0;
  3976.     Point                    myPoint;
  3977.     UInt32                    myNodeID;
  3978.     VRScriptClickSpritePtr    myPointer = NULL;
  3979.     VRScriptClickSpritePtr    myNext = NULL;
  3980.     ComponentResult            myErr = noErr;
  3981.     
  3982.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3983.     if (myAppData == NULL)
  3984.         goto bail;
  3985.  
  3986.     if (theEvent == NULL)
  3987.         goto bail;
  3988.         
  3989.     myHandler = (**myAppData).fSpriteHandler;
  3990.     myFlags = spriteHitTestImage | spriteHitTestLocInDisplayCoordinates | spriteHitTestInvisibleSprites;
  3991.     myPoint = theEvent->where;
  3992.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3993.     
  3994.     myErr = SpriteMediaHitTestAllSprites(myHandler, myFlags, myPoint, &myAtomID);
  3995.     if ((myErr == noErr) && (myAtomID != 0)) {
  3996.         
  3997.         // the user has clicked on a sprite;
  3998.         // walk the sprite-click command linked list and execute any that apply to that sprite in this node
  3999.         myPointer = (VRScriptClickSpritePtr)(**myAppData).fListArray[kVREntry_ClickSprite];
  4000.         while (myPointer != NULL) {
  4001.             myNext = myPointer->fNextEntry;
  4002.             
  4003.             if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  4004.                 if ((myPointer->fOptions == myAtomID) || (myPointer->fOptions == kVRAnySprite)) {
  4005.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  4006.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  4007.                 }
  4008.             }
  4009.         
  4010.             myPointer = myNext;
  4011.         }
  4012.  
  4013.         isHandled = true;
  4014.     }
  4015.     
  4016. bail:
  4017.     return(isHandled);
  4018. }
  4019.  
  4020.  
  4021. //////////
  4022. //
  4023. // VRScript_CheckForAngleCommands
  4024. // Walk through our linked lists of angle-triggered commands and see whether any need to be executed.
  4025. //
  4026. //////////
  4027.  
  4028. void VRScript_CheckForAngleCommands (WindowObject theWindowObject)
  4029. {
  4030.     ApplicationDataHdl        myAppData;
  4031.     VRScriptAtAnglePtr        myNext;
  4032.     VRScriptAtAnglePtr        myPointer;
  4033.     UInt32                    myNodeID;
  4034.     float                    myPan;
  4035.     float                    myTilt;
  4036.     float                    myFOV;
  4037.  
  4038.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  4039.     if (myAppData == NULL)
  4040.         return;
  4041.         
  4042.     // get the current environment
  4043.     myPan = QTVRGetPanAngle((**theWindowObject).fInstance);
  4044.     myTilt = QTVRGetTiltAngle((**theWindowObject).fInstance);
  4045.     myFOV = QTVRGetFieldOfView((**theWindowObject).fInstance);
  4046.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  4047.  
  4048.     // walk the pan angle linked list
  4049.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_PanAngleCmd];
  4050.     while (myPointer != NULL) {
  4051.         myNext = myPointer->fNextEntry;
  4052.  
  4053.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  4054.             if (myPointer->fMinAngle <= myPan)
  4055.                 if (myPointer->fMaxAngle >= myPan) {
  4056.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  4057.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  4058.                 }
  4059.         myPointer = myNext;
  4060.     }
  4061.  
  4062.     // walk the tilt angle linked list
  4063.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_TiltAngleCmd];
  4064.     while (myPointer != NULL) {
  4065.         myNext = myPointer->fNextEntry;
  4066.  
  4067.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  4068.             if (myPointer->fMinAngle <= myTilt)
  4069.                 if (myPointer->fMaxAngle >= myTilt) {
  4070.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  4071.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  4072.                 }
  4073.         myPointer = myNext;
  4074.     }
  4075.  
  4076.     // walk the zoom angle linked list
  4077.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_FOVAngleCmd];
  4078.     while (myPointer != NULL) {
  4079.         myNext = myPointer->fNextEntry;
  4080.  
  4081.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  4082.             if (myPointer->fMinAngle <= myFOV)
  4083.                 if (myPointer->fMaxAngle >= myFOV) {
  4084.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  4085.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  4086.                 }
  4087.         myPointer = myNext;
  4088.     }
  4089.  
  4090. }
  4091.  
  4092.  
  4093. //////////
  4094. //
  4095. // VRScript_CheckForExpiredCommand
  4096. // See whether the specified command entry has expired.
  4097. //
  4098. //////////
  4099.  
  4100. void VRScript_CheckForExpiredCommand (WindowObject theWindowObject, VRScriptGenericPtr thePointer)
  4101. {
  4102.     if (thePointer->fMaxExecutions != kVRDoIt_Forever)
  4103.         thePointer->fMaxExecutions--;
  4104.     if (thePointer->fMaxExecutions == 0)
  4105.         VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)thePointer);
  4106. }
  4107.  
  4108.  
  4109. //////////
  4110. //
  4111. // VRScript_DumpUnexpiredCommands
  4112. // Dump any unexpired AtTime commands, if the list entry so indicates.
  4113. // This is called only when leaving a node, to removed unexecuted ("orphaned") commands
  4114. // which would be executed the next time the user entered the node.
  4115. //
  4116. //////////
  4117.  
  4118. void VRScript_DumpUnexpiredCommands (WindowObject theWindowObject, UInt32 theNodeID)
  4119. {
  4120.     ApplicationDataHdl        myAppData;
  4121.     VRScriptAtTimePtr        myPointer;
  4122.     VRScriptAtTimePtr        myNext;
  4123.  
  4124.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  4125.     if (myAppData == NULL)
  4126.         return;
  4127.  
  4128.     // walk the linked list of timed commands and find any commands to be removed from list
  4129.     myPointer = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  4130.     while (myPointer != NULL) {
  4131.         myNext = myPointer->fNextEntry;
  4132.  
  4133.         if (myPointer->fNodeID == theNodeID)
  4134.             if (myPointer->fOptions == kVROrphan_Kill)
  4135.                 VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)myPointer);
  4136.         
  4137.         myPointer = myNext;
  4138.     }
  4139. }
  4140.  
  4141.  
  4142. //////////
  4143. //
  4144. // VRScript_PackString
  4145. // Pack a string.
  4146. //
  4147. //////////
  4148.  
  4149. void VRScript_PackString (char *theString)
  4150. {
  4151.     short        myLength;
  4152.     short        myIndex;
  4153.     
  4154.     myLength = strlen(theString);
  4155.     for (myIndex = 0; myIndex < myLength; myIndex++)
  4156.         if (isspace(theString[myIndex]))
  4157.             theString[myIndex] = '#';
  4158. }
  4159.  
  4160.  
  4161. //////////
  4162. //
  4163. // VRScript_UnpackString
  4164. // Unpack a string (for instance, to make a packed command line suitable for parsing by VRScript_ProcessScriptCommandLine).
  4165. //
  4166. // We allow embedding commands in other commands: '*' -> '&' -> '%' -> '#' -> ' '
  4167. //
  4168. //////////
  4169.  
  4170. void VRScript_UnpackString (char *theString)
  4171. {
  4172.     short        myLength;
  4173.     short        myIndex;
  4174.     
  4175.     myLength = strlen(theString);
  4176.     for (myIndex = 0; myIndex < myLength; myIndex++) {
  4177.         if (theString[myIndex] == '#')
  4178.             theString[myIndex] = ' ';
  4179.         if (theString[myIndex] == '%')
  4180.             theString[myIndex] = '#';
  4181.         if (theString[myIndex] == '&')
  4182.             theString[myIndex] = '%';
  4183.         if (theString[myIndex] == '*')
  4184.             theString[myIndex] = '&';
  4185.     }
  4186. }
  4187.  
  4188.  
  4189. //////////
  4190. //
  4191. // VRScript_DecodeString
  4192. // Decode a string, assumed to have been encoded using a simple rotate-11 scheme.
  4193. //
  4194. //////////
  4195.  
  4196. void VRScript_DecodeString (char *theString)
  4197. {
  4198.     short        myLength;
  4199.     short        myIndex;
  4200.     
  4201.     myLength = strlen(theString);
  4202.     for (myIndex = 0; myIndex < myLength; myIndex++)
  4203.         if (theString[myIndex] != '\n')
  4204.             theString[myIndex] = theString[myIndex] - 11;
  4205. }
  4206.  
  4207.  
  4208. //////////
  4209. //
  4210. // VRScript_StringToOSType
  4211. // Convert a string to an OSType.
  4212. //
  4213. //////////
  4214.  
  4215. OSType VRScript_StringToOSType (char *theString)
  4216. {
  4217.     unsigned long        myType = 0L;
  4218.     
  4219.     if (strlen(theString) < kMaxOSTypeLength - 1)
  4220.         return((OSType)myType);
  4221.         
  4222.     myType += theString[3] << 0;
  4223.     myType += theString[2] << 8;
  4224.     myType += theString[1] << 16;
  4225.     myType += theString[0] << 24;
  4226.     
  4227.     return((OSType)myType);
  4228. }
  4229.  
  4230.  
  4231. //////////
  4232. //
  4233. // VRScript_OSTypeToString
  4234. // Convert an OSType to a string.
  4235. //
  4236. // The caller is responsible for disposing of the pointer returned by this function (by calling free).
  4237. //
  4238. //////////
  4239.  
  4240. char *VRScript_OSTypeToString (OSType theType)
  4241. {
  4242.     char            *myString = malloc(kMaxOSTypeLength);
  4243.     
  4244.     if (myString == NULL)
  4245.         return(NULL);
  4246.         
  4247.     myString[0] = (theType & 0xff000000) >> 24;
  4248.     myString[1] = (theType & 0x00ff0000) >> 16;
  4249.     myString[2] = (theType & 0x0000ff00) >> 8;
  4250.     myString[3] = (theType & 0x000000ff) >> 0;
  4251.     myString[4] = '\0';
  4252.     
  4253.     return(myString);
  4254. }
  4255.  
  4256.  
  4257. //////////
  4258. //
  4259. // VRScript_FloatsAreEqual
  4260. // Are the specified floating-point numbers equal, within a specified tolerance?
  4261. //
  4262. //////////
  4263.  
  4264. Boolean VRScript_FloatsAreEqual (float theFloat1, float theFloat2, float theTolerance)
  4265. {
  4266.     Boolean            areEqual = false;
  4267.     float            myDifference;
  4268.     
  4269.     myDifference = theFloat1 - theFloat2;
  4270.     if (myDifference < 0.0)
  4271.         myDifference *= -1.0;
  4272.     
  4273.     if (myDifference <= theTolerance)
  4274.         areEqual = true;
  4275.     
  4276.     return(areEqual);
  4277. }
  4278.  
  4279.  
  4280.